&lt;?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Articles from November 2020 on PowerShell.org - Welcome Automaters!</title><link>https://powershell.org/articles/2020/11/</link><description>Recent content in Articles from November 2020 on PowerShell.org - Welcome Automaters!</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://powershell.org/articles/2020/11/index.xml" rel="self" type="application/rss+xml"/><item><title>Update: 2021 PowerShell + DevOps Global Summit</title><link>https://powershell.org/articles/2020-11-29-update-2021-powershell-devops-global-summit/</link><guid>https://powershell.org/articles/2020-11-29-update-2021-powershell-devops-global-summit/</guid><pubDate>Sun, 29 Nov 2020 18:00:38 +0000</pubDate><description>&lt;p&gt;Hello PowerShell and Automation family!&lt;/p&gt;
&lt;p&gt;It’s time to get excited for the PowerShell + DevOps Global Summit, which is 
returning April 27-29, 2021
as a virtual event&lt;/p&gt;
&lt;p&gt;. I’m here to share with you some details we have planned for this year’s event. The upcoming summit will differ from years past, since
this event will be 100% virtual
. You may wonder what a virtual event would be like, and is it worth it to attend?&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>Hello PowerShell and Automation family!</p><p>It’s time to get excited for the PowerShell + DevOps Global Summit, which is 
returning April 27-29, 2021
as a virtual event</p><p>. I’m here to share with you some details we have planned for this year’s event. The upcoming summit will differ from years past, since
this event will be 100% virtual
. You may wonder what a virtual event would be like, and is it worth it to attend?</p><p>**What is the PowerShell and DevOps Global Summit?
**PowerShell and DevOps experts from all over the world, including members from the PowerShell team, will join to discuss and learn about maximizing PowerShell in the workplace in 20+ fast-paced, knowledge-packed presentations. The Summit is also the place to explore and further your knowledge of DevOps principles and practices in a cross-platform environment. We will help you make new connections, learn new techniques, and offer something to your peers and colleagues when you return.</p><p><strong>When is the event?</strong></p><p>The event takes place</p><p>online from April 27-29, 2021</p><p>.</p><p>**Is this a free event?
**No,
it is not a free event
. The PowerShell Summit has always been a paid event, and this year is no different. The event will be online, but you will need to purchase a ticket to attend the sessions.
Tickets for past events have been approximately $1700 dollars each
.</p><p>The tickets for this year’s virtual event will be significantly less.</p><p>We’ll announce official ticket pricing at the end of December</p><p>.</p><p><strong>What will the tickets cost, and when can I buy them?
**
Tickets will go on sale Friday, January 15, 2021.
We will announce detailed ticket information at the end of December. The latest information can always can be found at our official event website:</strong><a href="https://events.devopscollective.org/event/powershell-devops-global-summit-2021/">PowerShellSummit.org</a>** .</p><p>**What is planned for the 2021 PowerShell and DevOps Global Summit?
**The PowerShell + Devops Global Summit has always been the premiere event of the year to meet people, share ideas and learn new concepts, and the next conference will be no different. We plan to have the same amazing opportunities for attendees to who attend this virtual PowerShell + Devops Global Summit.</p><p>The event this year will be three days long
and will feature some of the brightest minds in the community and from Microsoft. We strive to bring the best content to attendees each year, and this year will be no different.
Our event will have a minimum of 8 speaker led sessions each day for attendees to take part in
. Each session will have opportunities to talk with other attendees and ask the presenters questions. However, this will not be the same as attending an online meeting. The conferencing software will provide for a unique experience that will allow much greater participation than if you were attending a meeting with Teams or Zoom.</p><p>There will be keynote sessions
from prominent industry leaders and some deep-dive sessions from vendors who have generously supported our event.
We will also continue our tradition of presenting lightning demos
that are rapid fire, short 5 to 8 minute demos. Presenting the lightning demos in the past has always been a challenge of trying to fit in all the content in the limited time we had in a live event.
This year we will have more options for presenting lightning demos
and we expect to have more demos to share.</p><p>Besides the three-day event,
all sessions will be available on-demand for Summit attendees for an additional 12 months
; that includes keynotes, speaker &amp; vendor led sessions, and lightning demos. All content from the live event will be available on-demand, plus some additional content that won’t make it into the live event.</p><p>**What else is offered? **</p><p>Each attendee will have access to the recorded sessions after the Summit end for an additional 12 months. There will be some swag for attendees and opportunities to win additional swag from vendors.</p><p>**Who will be speaking at the PowerShell and DevOps Global Summit 2021?
**Great question! As always, our speakers are from and represent the community.
We will open our speaker submission process on Nov 30th
. Anyone can submit, but we’re
looking for the best of the best
. We are looking for a minimum of 30 speaker sessions, of which 24 will make it to the Summit live event. All accepted submissions will be available after the Summit ends via our Summit Archive catalog.
Anyone looking to submit a lightning demo can also start submitting on Nov 30th
. We’ll have a separate announcement about the submission process and the details involved in that process later in the week.</p><p>Our submission process will continue until Jan 15th, 2021<strong>.</strong> Once the submission process ends, we will announce the lineup for speakers publicly. Besides our community speakers,</p><p>members of the Microsoft PowerShell team will perform community demos and share product announcements</p><p>.</p>
]]></content:encoded></item><item><title>ICYMI: PowerShell Week of 20-November-2020</title><link>https://powershell.org/articles/2020-11-20-icymi-powershell-week-of-20-november-2020/</link><guid>https://powershell.org/articles/2020-11-20-icymi-powershell-week-of-20-november-2020/</guid><pubDate>Fri, 20 Nov 2020 20:00:25 +0000</pubDate><description>&lt;p&gt;Topics include Splatting, Print Servers, Active Directory and more&amp;hellip;&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>Topics include Splatting, Print Servers, Active Directory and more&hellip;</p><p>Special thanks to Robin Dadswell, Prasoon Karunan V, Kiran Patnayakuni and Kevin Laux.</p><h6 id="using-the-powershell-formatting-system-to-your-advantage" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#using-the-powershell-formatting-system-to-your-advantage"/><a href="https://joskw.gitbook.io/blog/object_formatting"><em>Using the PowerShell formatting system to your advantage</em></a><a class="ps-heading-anchor" href="#using-the-powershell-formatting-system-to-your-advantage" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Jos Koelewijn on 15th November<br>
A nice walkthrough of how PowerShell displays output.</p><h6 id="answering-the-powershell-registered-user-challenge" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#answering-the-powershell-registered-user-challenge"/><a href="https://jdhitsolutions.com/blog/powershell/7881/answering-the-powershell-registered-user-challenge/"><em>Answering the PowerShell Registered User Challenge</em></a><a class="ps-heading-anchor" href="#answering-the-powershell-registered-user-challenge" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Jeff Hicks on 16th November<br>
Take a look at Jeff&rsquo;s solution for the recent Iron Scripter Challenge around a computer&rsquo;s registered user.</p><h6 id="documenting-with-powershell-documenting-print-servers" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#documenting-with-powershell-documenting-print-servers"/><a href="https://www.cyberdrain.com/documenting-with-powershell-documenting-print-servers/%7Chttps://www.cyberdrain.com/documenting-with-powershell-documenting-print-servers/"><em>Documenting with PowerShell: Documenting Print Servers</em></a><a class="ps-heading-anchor" href="#documenting-with-powershell-documenting-print-servers" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Kelvin Tegelaar on 17th November<br>
Before I start on this; I agree. Printers are the bane of our existence in IT and I am hoping for a paperless environment each day. Unfortunately we’re not at that future just yet, so we have to document print servers and their settings.</p><h6 id="powershell-splatting-what-is-it-and-how-does-it-work" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#powershell-splatting-what-is-it-and-how-does-it-work"/><a href="https://adamtheautomator.com/powershell-splatting-what-is-it-and-how-does-it-work/"><em>PowerShell Splatting: What is it and How Does it Work?</em></a><a class="ps-heading-anchor" href="#powershell-splatting-what-is-it-and-how-does-it-work" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Adam Listek on 18th November<br>
In this article, you’ll learn how best to use PowerShell splatting to enhance your scripts and code!</p><h6 id="reddit-rpowershell---most-popular-weekly-post" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#reddit-rpowershell---most-popular-weekly-post"/><a href="https://www.reddit.com/r/PowerShell/comments/juolpi/whats_the_last_really_useful_powershell_technique/"><em>Reddit /r/PowerShell - Most Popular Weekly Post</em></a><a class="ps-heading-anchor" href="#reddit-rpowershell---most-popular-weekly-post" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>Reddit users share recent PowerShell tips they have learned.</p><h6 id="tweet-of-the-week" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#tweet-of-the-week"/><a href="https://twitter.com/joeyaiello/status/1328836828124745730"><em>Tweet of the Week</em></a><a class="ps-heading-anchor" href="#tweet-of-the-week" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>If you&rsquo;re already bored of the #PowerShell 7.1 GA, don&rsquo;t fret! The first PowerShell 7.2 preview is already live</p><h6 id="youtube-active-directory-automation-with-powershell" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201120-functiondraft.md#youtube-active-directory-automation-with-powershell"/><a href="https://www.youtube.com/watch?v=3k9xcPtE7Cs"><em>Youtube: Active Directory automation with PowerShell</em></a><a class="ps-heading-anchor" href="#youtube-active-directory-automation-with-powershell" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>Live stream showing off using PowerShell for working in Active Directory.</p>]]></content:encoded></item><item><title>ICYMI: PowerShell Week of 13-November-2020</title><link>https://powershell.org/articles/2020-11-13-icymi-powershell-week-of-13-november-2020/</link><guid>https://powershell.org/articles/2020-11-13-icymi-powershell-week-of-13-november-2020/</guid><pubDate>Fri, 13 Nov 2020 15:00:28 +0000</pubDate><description>&lt;p&gt;Topics include Teams, Azure, Tic-Tac-Toe and more&amp;hellip;&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>Topics include Teams, Azure, Tic-Tac-Toe and more&hellip;</p><p>Special thanks to Robin Dadswell, Prasoon Karunan V, Kiran Patnayakuni and Kevin Laux.</p><h6 id="introducing-psteams-20--support-for-adaptive-cards-hero-cards-list-cards-and-thumbnail-cards" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#introducing-psteams-20--support-for-adaptive-cards-hero-cards-list-cards-and-thumbnail-cards"/><a href="https://evotec.xyz/introducing-psteams-2-0-support-for-adaptive-cards-hero-cards-list-cards-and-thumbnail-cards/"><em>Introducing PSTeams 2.0 – Support for Adaptive Cards, Hero Cards, List Cards and Thumbnail Cards</em></a><a class="ps-heading-anchor" href="#introducing-psteams-20--support-for-adaptive-cards-hero-cards-list-cards-and-thumbnail-cards" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Przemyslaw Klys on 9th November<br>
Let&rsquo;s look at enhancements in the Teams PS module about what type of cards that can now be sent via PowerShell.</p><h6 id="how-to-survive-refactoring-a-powershell-script-from-hell" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#how-to-survive-refactoring-a-powershell-script-from-hell"/><a href="https://adamtheautomator.com/how-to-survive-refactoring-a-powershell-script-from-hell/"><em>How to Survive Refactoring a PowerShell Script from Hell.</em></a><a class="ps-heading-anchor" href="#how-to-survive-refactoring-a-powershell-script-from-hell" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Adam Bertram on 10th November<br>
If you’ve ever inherited a script or set of PowerShell scripts, you probably know the frustration. You have a specific way of coding honed over years and years of experience and you come across a… let’s say monstrosity.</p><h6 id="announcing-psreadline-21-with-predictive-intellisense" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#announcing-psreadline-21-with-predictive-intellisense"/><a href="https://devblogs.microsoft.com/powershell/announcing-psreadline-2-1-with-predictive-intellisense/"><em>Announcing PSReadLine 2.1+ with Predictive IntelliSense</em></a><a class="ps-heading-anchor" href="#announcing-psreadline-21-with-predictive-intellisense" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Jason Helmick on 10th November<br>
With the latest release of PowerShell and PSReadLine Beta version, Jason walks us through how to enable and make use of predictive IntelliSense.</p><h6 id="announcing-az-predictor" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#announcing-az-predictor"/><a href="https://techcommunity.microsoft.com/t5/azure-tools/announcing-az-predictor/ba-p/1873104"><em>Announcing Az Predictor.</em></a><a class="ps-heading-anchor" href="#announcing-az-predictor" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Damien Caro on 11th November<br>
The Azure PowerShell modules expose over 4,000 cmdlets and, on average, ten parameters per cmdlet. Experienced PowerShell users will find the right cmdlet and parameter to achieve their goal but this can be more complicated for casual users.</p><h6 id="better-performance-counters-with-powershell" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#better-performance-counters-with-powershell"/><a href="https://jdhitsolutions.com/blog/powershell/7872/better-performance-counters-with-powershell/"><em>Better Performance Counters with PowerShell</em></a><a class="ps-heading-anchor" href="#better-performance-counters-with-powershell" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>by Jeff Hicks on 12th November<br>
Jeff Hicks show us a new addition to the latest release of PSScriptTools around Performance Counters.</p><h6 id="reddit-rpowershell---most-popular-weekly-post" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#reddit-rpowershell---most-popular-weekly-post"/><a href="https://www.reddit.com/r/PowerShell/comments/jprdli/tictactoe_in_powershell"><em>Reddit /r/PowerShell - Most Popular Weekly Post</em></a><a class="ps-heading-anchor" href="#reddit-rpowershell---most-popular-weekly-post" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>u/Fireburd55 made tic-tac-toe in PowerShell and wanted to share it with the community.</p><h6 id="tweet-of-the-week" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#tweet-of-the-week"/><a href="https://twitter.com/joeyaiello/status/1326666733000650752"><em>Tweet of the Week</em></a><a class="ps-heading-anchor" href="#tweet-of-the-week" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>Whether you&rsquo;re a #PowerShell 7.0 user or a Windows PowerShell diehard, make sure to check out latest GA release of PowerShell 7.1!</p><h6 id="youtube-catch-me-if-you-can-powershell-red-vs-blue" class="ps-heading"><a href="https://github.com/devops-collective-inc/WhatYouMissedThisWeek/blob/master/20201113-functiondraft.md#youtube-catch-me-if-you-can-powershell-red-vs-blue"/><a href="https://www.youtube.com/watch?v=anFe9PZn3eg"><em>Youtube: Catch Me If You Can: PowerShell Red vs Blue</em></a><a class="ps-heading-anchor" href="#youtube-catch-me-if-you-can-powershell-red-vs-blue" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p>A talk about how security and PowerShell interact and in some cases cause problems for each other.</p>]]></content:encoded></item><item><title>ICYMI: PowerShell Week of 06-November-2020</title><link>https://powershell.org/articles/2020-11-06-icymi-powershell-week-of-06-november-2020/</link><guid>https://powershell.org/articles/2020-11-06-icymi-powershell-week-of-06-november-2020/</guid><pubDate>Fri, 06 Nov 2020 15:00:57 +0000</pubDate><description>&lt;p&gt;Topics include Containers, Microsoft Teams, AMSI and more&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>Topics include Containers, Microsoft Teams, AMSI and more</p><p>Special thanks to Robin Dadswell, Prasoon Karunan V, Kiran Patnayakuni and Kevin Laux.</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://www.techlila.com/powershell-vs-cmd/"><em>Windows PowerShell vs CMD – What’s the Difference</em></a></p><p>by Ankush Das on 2nd November</p><p>Most of you must have used the command prompt at some point in time – whether just for the sake of trying out an experiment or fixing an issue like recovering the data after getting affected by a shortcut virus. But, what about PowerShell which came into existence later? What is the difference between PowerShell and cmd?</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://www.phillipsj.net/posts/powershell-and-containers/"><em>PowerShell and Containers</em></a></p><p>by Jamie Phillips on 2nd November</p><p>Jamie demonstrates how to run PowerShell scripts inside the containers.</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://adamtheautomator.com/back-to-basics-how-to-manage-windows-services-with-powershell/"><em>Back to Basics: How to Manage Windows Services with PowerShell</em></a></p><p>by Adam Bertram on 3rd November</p><p>Learn how to get, start, stop, and restart services with Adam Bertram.</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="http://www.blogabout.cloud/2020/11/1930"><em>Quick Tips: How do I restore a deleted Microsoft Teams Team using PowerShell.</em></a></p><p>by Andrew Price on 5th November</p><p>When the team is deleted, it is held in the “recycle bin” for 30 days until it is permanently deleted. The following is the process of restoring a deleted team in Microsoft Teams.</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://medium.com/bugbountywriteup/bypass-amsi-in-powershell-a-nice-case-study-f3c0c7bed24d"><em>Bypass AMSI in PowerShell — A Nice Case Study</em></a></p><p>by Aidin Naserifard on 5th November</p><p>Bypass AMSI in PowerShell — A Nice Case Study</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://www.reddit.com/r/PowerShell/comments/joiabt/selectstring_with_regex/"><em>Reddit /r/PowerShell - Most Popular Weekly Post</em></a></p><p>working with select-string cmdlet.</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://twitter.com/Steve_MSFT/status/1323408339078946816"><em>Tweet of the Week</em></a></p><p>PSReadLine 2.1.0 GA has been published!</p><h6 id="" class="ps-heading"><a class="ps-heading-anchor" href="#" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h6><p><a href="https://www.youtube.com/watch?v=E8zJyr_OZJ0&amp;feature=emb_logo"><em>Youtube: How to hide the analyzer false positives?</em></a></p><p>How to hide the analyzer false positives?</p>]]></content:encoded></item><item><title>Writing Your Own PowerShell Functions / Cmdlets</title><link>https://powershell.org/articles/2020-11-05-writing-your-own-powershell-functions-cmdlets/</link><guid>https://powershell.org/articles/2020-11-05-writing-your-own-powershell-functions-cmdlets/</guid><pubDate>Thu, 05 Nov 2020 18:53:35 +0000</pubDate><description>&lt;p&gt;This article is an attempt at describing some of my thought process when building functions. By functions I mean a command that you can execute after importing a module. I am not referring to running a script that accepts parameters and input. Having a task to complete for a function is of course the first objective. Once an idea is in mind I like to write as much as the Help section first as possible as this helps me outline and plan what I am going to do.&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>This article is an attempt at describing some of my thought process when building functions. By functions I mean a command that you can execute after importing a module. I am not referring to running a script that accepts parameters and input. Having a task to complete for a function is of course the first objective. Once an idea is in mind I like to write as much as the Help section first as possible as this helps me outline and plan what I am going to do.</p><p><strong>Writing The Help Section</strong></p><p>Start with the easy part first, the<strong>SYNOPSIS</strong>. Best practice for this states that you should NOT include the name of your function or cmdlet in this section of the help. The idea behind this is similar to the idea that you do not want to use a word to define a word. That is one of those things that has always driven me crazy so I make a point to not be one of the references that does that. This section should be a very short description of what your cmdlet does. I typically start this sentence with the phrase format; &ldquo;This cmdlet was created to accomplish this task on local and remote devices using WinRM to connect to remote devices&rdquo;.</p><p>The next part I start to write is the<strong>DESCRIPTION</strong>. Depending on how much you have planned out in your head you may not delve to deeply into this section yet. This is the area where you add details that may be useful to know about your function as well as instructions and insights. This might include information on how the pipeline works or settings required for the command to work.</p><p>With those descriptions fresh in mind I like to start the<strong>PARAMETER</strong> section. Parameter names should be singular and not plural, even if your parameter is an array. You do not need to get all of these ahead of time however, if you know you want your cmdlet to work on remote devices it is a good idea to start with the &ldquo;ComputerName&rdquo; parameter and if you are using WinRM use the &ldquo;UseSSL&rdquo; Parameter to cover all environment situations as best you can. Underneath the parameter&rsquo;s name in the help section you should provide a brief description of the parameters use to describe what the parameter is and the default value if you plan on giving it one. It is best practice to name the parameter with something typical of PowerShell. This is for interoperability as well as maintaining a set of standards. For example, I used the parameter title &ldquo;ComputerName&rdquo; and not hostname or FQDN. This should pretty much be the case for that situation every time. In a few cases, Computer is an acceptable parameter. An example of a case where this is acceptable is when your cmdlet is going to be passing the value of the $Computer parameter to a cmdlet that uses -Computer instead of -ComputerName. One such function that uses -Computer is Invoke-GPUpdate. With the &ldquo;Computer&rdquo; parameter value going into the Invoke-GPUpdate cmdlet it is best practice to use Computer and not ComputerName. Another thing I do sometimes is if I am going to use the -ComputerName parameter to pass the value to &ldquo;Invoke-Command&rdquo; or &ldquo;New-PSSession&rdquo; I do the below command :</p><p><code>Get-Help -Name Invoke-Command -Parameter ComputerName</code></p><p>I then copy and paste the description of that parameter into my functions description for that parameter since they are basically mirrored. This is a good way to provide the best information possible.</p><p>The<strong>EXAMPLE</strong> section I do not write until after I have completed the function. This prevents the need to make any unnecessary changes later on to this section. I have made assumptions thinking this section is done and it is left outdated using parameters that don&rsquo;t exist anymore. That is why I believe this is easiest to do last. If your command accepts pipeline input you should have an example demonstrating how that works and not just assume people will understand by reading everything else you have written. This may be the only thing they read. You should also demonstrate each parameter at least one of your examples. The more use cases you can come up with the better. I have found this practice to really improve my function development as well as my understanding of how PowerShell works. After each command example use a commented line to add a description of what each command example is accomplishing.</p><p>In the<strong>NOTES</strong> section I typically put my name as the author and contact information if someone needs to contact me on the function for whatever reason. Notes about your function can be added here as well.</p><p>I use the<strong>LINK</strong> section to include any documentation I may have used to write the cmdlet however this typically just includes links to my GitHub and other sites related to myself.</p><p>The<strong>INPUTS</strong> section is for defining the .NET class types that your cmdlet accepts as input from the pipeline. Most of the time this is going to be something like System.String or System.Array when used. If you do not have the property value &ldquo;ValueFromPipeline=$True&rdquo; set on any of your parameters, the INPUTS section should be set to &ldquo;None&rdquo;. If you are piping input to a specific cmdlet you can pull the trick I did earlier to obtain the INPUTS information using the below command:</p><p><code>Get-Help -Name Enter-PSSession -Full | Out-String -Stream | Select-String -Pattern "INPUTS" -Context 1,4</code></p><p>The<strong>OUTPUTS</strong> section is the .NET class type that your cmdlet returns as a value(s). One thing I have been meaning to do to work on expanding my knowledge is to consistently add the expected returned Outputs to the CmdletBinding property in my functions.</p><p><strong>Outlining The Function</strong></p><p>We are now ready to start working on the function. To name the function we need to use one of the PowerShell approved &ldquo;Verbs&rdquo;. Use the command &ldquo;Get-Verb&rdquo; to retrieve a list of possible options as well as what they refer too. It is best practice to use these verbs as they will help with how PowerShell accepts pipeline input. If you need help in choosing a verb for your function I suggest checking out this<a href="https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands?view=powershell-7">Microsoft article</a>.<br>
    If you are going to accept pipeline input in your function; (<em>One of your parameter properties has a value of &ldquo;ValueFromPipeline=$True&rdquo;</em>) ; you should start out by creating 3 sections. Begin, Process, and End. For each value in the pipeline being passed to your function, the begin section will be carried out first. Typically I use the Begin section to</p><ul><li>Import modules if any are needed</li><li>Define any variables that need to be defined</li><li>Ensure values are correct if not done already using something such as &ldquo;ValidateScript&rdquo;.</li></ul><p>Everything in the Begin brackets get executed before moving to the Process brackets and so forth. &ldquo;Begin&rdquo; is optional really as is the &ldquo;End&rdquo; section.</p><p>    The &ldquo;End&rdquo; section I use to</p><ul><li>Close any open sessions</li><li>Clear variables if that needs to be done</li><li>Return the object or results of the Process section</li></ul><p>The Process section should contain the meat of your cmdlets. This is going to be where the main purpose of your function is carried out.</p><p>If you are not using pipeline input in your function you do not need to include those 3 sections. You can simply just start putting together whatever you need.</p><p><strong>Example Using Information So Far</strong></p><p>The example function I am going to use here will be for a function I created to encode and decode Base64 values. The verb I am going to use is &ldquo;Convert&rdquo;. I chose this value because the cmdlet is going to be changing the data from one representation to another. The Noun I am going to choose can be whatever I want really. To make the cmdlet easy to understand I am going to name it Convert-Base64. I could choose to create two different functions, for example ConvertTo-Base64 and ConvertFrom-Base64. I would personally rather use one command to perform both tasks as this is the kind of function that typically gets used both ways. Now that I know the name of my function I can write my help section which is below.</p><p>You can see from the above section that I have a good idea of how this is going to work. I next start my functions build by defining my parameters. I typically will always add<strong>[CmdletBinding()]</strong> to my functions. What this does is allow the use of 7 common parameters in PowerShell functions. Some examples of these are -Verbose, Debug, ErrorAction, ErrorVariable, etc. This also allows me to easily define a Default Parameter Set name which I have found to be a great way of simplifying my functions and improving execution times.</p><p><code>Function Convert-Base64 { [CmdletBinding(DefaultParameterSetName='Encode')] param( [Parameter( Mandatory=$True, Position=0, ValueFromPipeline=$True, HelpMessage="Enter a string you wish to encode or decode using Base64. Example: Hello World!")] # End Parameter [String]$Value, [Parameter( ParameterSetName='Encode', Mandatory=$True)] [Switch][Bool]$Encode, [Parameter( ParameterSetName='Decode', Mandatory=$True)] [Switch][Bool]$Decode, [Parameter( Mandatory=$False, ValueFromPipeline=$False)] # End Parameter [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')] [String]$TextEncoding = 'UTF8' ) # End param BEGIN {...}}</code>Notice in the above I have two &ldquo;Switch&rdquo; parameters. I have given them bool values so I can use the attribute &ldquo;IsPresent&rdquo; in any &ldquo;If&rdquo; statements that come up. For example I could do</p><p><code>If ($Encode.IsPresent) { $Value = 'Encode' }</code>I have also created two parameter set names. The reason for this is to ensure that only one option or the other is selected. We need to know whether to Encode or Decode the -Value parameters value. This prevents errors from occurring because the person executing the function may think extra parameters need to be defined. This may not always be as intuitive as this function. It is a best practice that should be adhered too. It eliminates the need to add code in your function that attempts to accomplish this same task. For example, if you did not create the Parameter Set names you would need to do this in your &ldquo;BEGIN&rdquo; brackets to ensure one of the other was defined.</p><p><code>If (!($Encode.IsPresent -or $Decode.IsPresent)) { Throw "Switch parameter -Decode or -Encode needs to be defined. " } # End If</code>The Parameter &ldquo;Value&rdquo; is mandatory and accepts pipeline input. I did not include the property &ldquo;ValueFromPipelineByPropertyName&rdquo; because we want to convert a string and not just the property value of a PowerShell object. This places a limitation on the kind of value placed to cmdlet which we do not want in this scenario. The HelpMessage property for this parameter can be used here because the &ldquo;Value&rdquo; property is Mandatory. If the property is not included when the cmdlet is executed, PowerShell will prompt the executor for this value using the message you define there. If you are familiar with bash and python you probably are familiar with positional parameters. This is the same concept here when defining the Position value. I like to set this value to prevent the need for someone using the cmdlet to enter each parameter value. Position=0 is referring to the first value after Convert-Base64. In an example this gives us the ability to do:</p><p><code>Convert-Base64 'Convert me to base64' -Encode</code>Instead of:</p><p><code>Convert-Base64 -Value 'Convert me to base64' -Encode</code>We can also prevent the need to include -Encode by setting a default Parameter Set Name value. This is done by changing</p><p><code>[CmdletBinding()]</code>To</p><p><code>[CmdletBinding(DefaultParameterSetName='Encode')]</code>The person executing the command can now simply do this to encode their string :</p><p><code>Convert-Base64 'Convert me to base64'</code>In the &ldquo;TextEncoding&rdquo; parameter I did my best to name this as I do not know of any functions that offer this kind of option. I have added<strong>[ValidateSet()]</strong> to this parameter because I know all the possible values that can be used and we do not want anything else to be in this value. This also creates a Tab Autocomplete for the person using the cmdlet which saves typing as well. Other options that can be used to validate parameter values are<strong>ValidateRange</strong> and<strong>ValidateScript</strong>. These are the 3 I use most often. Validate your parameters whenever possible as this shows a professionalism in your abilities and will set you apart from others. It also ensures that your cmdlets work as expected. In the PROCESS area of my cmdlet I am using the .NET object System.Text.Encoding to convert the base64 related values. I used Tab autocomplete to come up with the list in &ldquo;ValidateSet&rdquo;.</p><p><code>[ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7')]</code>**
Building the Body of the Cmdlet
**</p><p>There are a couple of values that exist by default in every function. The main ones to know that get used often are PSCmdlet and PSBoundParameters. I often use these in Switch statements to help guide the direction of my functions script execution. For example you could do something such as</p><p><strong>$PSCmdlet.ParameterSetName</strong> to refer to the parameter set name your function is using. In my example, the default value for this would be &lsquo;Encode&rsquo;. You can also return the value of your parameters using<strong>$PSBoundParameters.Keys.Value</strong></p><p>In our situation there is not really a good way to use the BEGIN brackets. This section is optional so I am going to jump right into the PROCESS brackets. I am going to add a Switch statement to my PROCESS brackets using $PSCmdlet.ParameterSetName. If the parameter set name is Encode the commands inside the brackets next to encode will be executed. Same goes for Decode if that is the parameter set name defined.</p><p><code>PROCESS { Switch ($PSCmdlet.ParameterSetName) { 'Encode' { } 'Decode' { } } # End Switch</code>Now that the cmdlet knows which action to carry out, I need to work with the next parameter value needed to be defined before the convert action can be taken. This is the &ldquo;TextEncoding&rdquo; parameter. I am going to make another switch statement for this.</p><p><strong>NOTE</strong>: As a side note Switch statements are faster than If statements in situations such as this where we have a good amount of options to filter through.</p><p>Below is my switch statement. I am using this to convert the string value into whatever character encoding I want converted to Base64.</p><p><code>Switch ($TextEncoding) { 'ASCII' {$StringValue = [System.Text.Encoding]::ASCII.GetBytes("$Value")} 'BigEndianUnicode' {$StringValue = [System.Text.Encoding]::BigEndianUnicode.GetBytes("$Value")} 'Default' {$StringValue = [System.Text.Encoding]::Default.GetBytes("$Value")} 'Unicode' {$StringValue = [System.Text.Encoding]::Unicode.GetBytes("$Value")} 'UTF32' {$StringValue = [System.Text.Encoding]::UTF32.GetBytes("$Value")} 'UTF7' {$StringValue = [System.Text.Encoding]::UTF7.GetBytes("$Value")} 'UTF8' {$StringValue = [System.Text.Encoding]::UTF8.GetBytes("$Value")} } # End Switch</code>Once that value is defined the convert operation can be carried out. Error handling is another important aspect of cmdlet building. Typically we can accomplish this using Try Catch statements. Also using the -ErrorVariable parameter of a cmdlet is a great way to handle errors and redirect your functions execution.</p><p><strong>NOTE</strong>: A good thing to know about Try Catch is there is a third option called Finally. If you were to stop the execution of a function using Ctrl + C while inside of a Try Catch statement, the code inside the Finally brackets will still execute. This is great for leaving an infinite"While" loop with a message like &ldquo;Exiting loop&rdquo;.</p><p>Below is the Try Catch statement I have added:</p><p><code>Try { [System.Convert]::ToBase64String($StringValue) } # End Try Catch { Throw "String could not be converted to Base64. The value entered is below.</code>n$Value"
$Error[0]
} # End Catch
`Notice the value<strong>$Error[0]</strong> I have included in the Catch brackets. This is another value that is automatically assigned when an error occurs inside a cmdlet. Using the first positional value &ldquo;0&rdquo; of $Error will put the PowerShell generated error message on screen. Otherwise the only message being displayed would be mine which is not going to give information on what caused the error. You are able to add multiple catch statements where you can catch specific error types to provide your own messaging in each situation. To do this you need to know the object name of the error that will occur. Just to provide an example of this you could catch incorrectly entered credentials in a catch statement using the below:</p><p><code>Catch [System.Security.Authentication.AuthenticationException] { Throw "The credentials you entered were incorrect" } # End Catch Catch { $Error[0] }</code>The END brackets are also optional. Usually I use this area to close any session connections and to build a custom object. However to save script execution time, I am not going to do include that in this cmdlet. Whatever results are returned from the Try Catch statements is going to be the result of the command. The final result of these efforts can be view in the code below or at this<a href="https://github.com/tobor88/PowerShell-Red-Team/blob/master/Convert-Base64.ps1">LINK:</a></p><p>`&lt;#
.SYNOPSIS
This cmdlet is used to Encode or Decode Base64 strings.
.DESCRIPTION
Convert a string of text to or from Base64 format. Pipeline input is accepted in string format. Use the switch parameters Encode or Decode to define which action you wish to perform on your string
.PARAMETER Value
Defines the string to be encoded or decoded with base64.
.PARAMETER Encode
This switch parameter is used to tell the cmdlet to encode the base64 string
.PARAMETER Decode
This switch parameter is used to tell the cmdlet to decode the base64 string
.PARAMETER TextEncoding
This parameter is used to define the type of Unicode Character encoding to convert with Base64. This value you can be ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, or UTF8. The default value is UTF8
.EXAMPLE
Convert-Base64 -Value &lsquo;Hello World!&rsquo;&rsquo; -Encode</p><h1 id="this-example-encodes-hello-world-into-base64-format" class="ps-heading">This example encodes &ldquo;Hello World into Base64 format.<a class="ps-heading-anchor" href="#this-example-encodes-hello-world-into-base64-format" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h1><p>.EXAMPLE
Convert-Base64 -Value &lsquo;SGVsbG8gV29ybGQh&rsquo; -Decode -Encoding ASCII</p><h1 id="this-example-decodes-base64-to-a-string-in-ascii-format" class="ps-heading">This example decodes Base64 to a string in ASCII format<a class="ps-heading-anchor" href="#this-example-decodes-base64-to-a-string-in-ascii-format" aria-label="Link to this section" title="Link to this section"><i class="fas fa-link" aria-hidden="true"/></a></h1><p>.NOTES
Author: Robert H. Osborne
Alias: tobor
Contact:<a href="mailto:rosborne@osbornepro.com">rosborne@osbornepro.com</a>
.LINK<a href="https://roberthsoborne.com">https://roberthsoborne.com</a><a href="https://osbornepro.com">https://osbornepro.com</a><a href="https://btps-secpack.com">https://btps-secpack.com</a><a href="https://github.com/tobor88">https://github.com/tobor88</a><a href="https://gitlab.com/tobor88">https://gitlab.com/tobor88</a><a href="https://www.powershellgallery.com/profiles/tobor">https://www.powershellgallery.com/profiles/tobor</a><a href="https://www.linkedin.com/in/roberthosborne/">https://www.linkedin.com/in/roberthosborne/</a><a href="https://www.youracclaim.com/users/roberthosborne/badges">https://www.youracclaim.com/users/roberthosborne/badges</a><a href="https://www.hackthebox.eu/profile/52286">https://www.hackthebox.eu/profile/52286</a>
.INPUTS
System.String, -Value accepts strings from pipeline.
.OUTPUTS
System.String
#&gt;
Function Convert-Base64 {
[CmdletBinding(DefaultParameterSetName=&lsquo;Encode&rsquo;)]
param(
[Parameter(
Mandatory=$True,
Position=0,
ValueFromPipeline=$True,
HelpMessage=&ldquo;Enter a string you wish to encode or decode using Base64. Example: Hello World!&rdquo;)] # End Parameter
[String]$Value,
[Parameter(
ParameterSetName=&lsquo;Encode&rsquo;,
Mandatory=$True)]
[Switch][Bool]$Encode,
[Parameter(
ParameterSetName=&lsquo;Decode&rsquo;,
Mandatory=$True)]
[Switch][Bool]$Decode,
[Parameter(
Mandatory=$False,
ValueFromPipeline=$False)] # End Parameter
[ValidateSet(&lsquo;ASCII&rsquo;, &lsquo;BigEndianUnicode&rsquo;, &lsquo;Default&rsquo;, &lsquo;Unicode&rsquo;, &lsquo;UTF32&rsquo;, &lsquo;UTF7&rsquo;, &lsquo;UTF8&rsquo;)]
[String]$TextEncoding = &lsquo;UTF8&rsquo;
) # End param
PROCESS
{
Switch ($PSCmdlet.ParameterSetName)
{
&lsquo;Encode&rsquo; {
Switch ($TextEncoding)
{
&lsquo;ASCII&rsquo; {$StringValue = [System.Text.Encoding]::ASCII.GetBytes("$Value&rdquo;)}
&lsquo;BigEndianUnicode&rsquo; {$StringValue = [System.Text.Encoding]::BigEndianUnicode.GetBytes("$Value")}
&lsquo;Default&rsquo; {$StringValue = [System.Text.Encoding]::Default.GetBytes("$Value")}
&lsquo;Unicode&rsquo; {$StringValue = [System.Text.Encoding]::Unicode.GetBytes("$Value")}
&lsquo;UTF32&rsquo; {$StringValue = [System.Text.Encoding]::UTF32.GetBytes("$Value")}
&lsquo;UTF7&rsquo; {$StringValue = [System.Text.Encoding]::UTF7.GetBytes("$Value")}
&lsquo;UTF8&rsquo; {$StringValue = [System.Text.Encoding]::UTF8.GetBytes("$Value")}
} # End Switch
Try
{
[System.Convert]::ToBase64String($StringValue)
} # End Try
Catch
{
Throw &ldquo;String could not be converted to Base64. The value entered is below.<code>n$Value" $Error[0] } # End Catch } # End Switch Encode 'Decode' { $EncodedValue = [System.Convert]::FromBase64String("$Value") Switch ($TextEncoding) { 'ASCII' { Try { [System.Text.Encoding]::ASCII.GetString($EncodedValue) } # End Try Catch { Throw "Base64 entered was not in a correct format. The value received is below.</code>n$Value&rdquo;
} # End Catch
} # End Switch ASCII
&lsquo;BigEndianUnicode&rsquo; {
Try
{
[System.Text.Encoding]::BigEndianUnicode.GetString($EncodedValue)
} # End Try
Catch
{
Throw &ldquo;Base64 entered was not in a correct format. The value received is below.<code>n$Value" } # End Catch } # End Switch BigEndianUnicode 'Default' { Try { [System.Text.Encoding]::Default.GetString($EncodedValue) } # End Try Catch { Throw "Base64 entered was not in a correct format. The value received is below.</code>n$Value&rdquo;
} # End Catch
} # End Switch Default
&lsquo;Unicode&rsquo; {
Try
{
[System.Text.Encoding]::Unicode.GetString($EncodedValue)
} # End Try
Catch
{
Throw &ldquo;Base64 entered was not in a correct format. The value received is below.<code>n$Value" } # End Catch } # End Switch Unicode 'UTF32' { Try { [System.Text.Encoding]::UTF32.GetString($EncodedValue) } # End Try Catch { Throw "Base64 entered was not in a correct format. The value received is below.</code>n$Value&rdquo;
} # End Catch
} # End Switch UTF32
&lsquo;UTF7&rsquo; {
Try
{
[System.Text.Encoding]::UTF7.GetString($EncodedValue)
} # End Try
Catch
{
Throw &ldquo;Base64 entered was not in a correct format. The value received is below.<code>n$Value" } # End Catch } # End Swithc UTF7 'UTF8' { Try { [System.Text.Encoding]::UTF8.GetString($EncodedValue) } # End Try Catch { Throw "Base64 entered was not in a correct format. The value received is below.</code>n$Value&rdquo;
} # End Catch
} # End Switch UTF8
} # End Switch
} # End Switch Decode
} # End Switch
} # End PROCESS
} # End Function Convert-Base64
`Thanks for reading!</p><ul><li><a href="https://roberthosborne.com">tobor</a></li></ul>
]]></content:encoded></item><item><title>The Return of the PowerShell + DevOps Global Summit</title><link>https://powershell.org/articles/2020-11-03-the-return-of-the-powershell-devops-global-summit/</link><guid>https://powershell.org/articles/2020-11-03-the-return-of-the-powershell-devops-global-summit/</guid><pubDate>Tue, 03 Nov 2020 16:00:00 +0000</pubDate><description>&lt;p&gt;The DevOps Collective INC is pleased to announce the return of the PowerShell + DevOps Global Summit in April of 2021.&lt;/p&gt;
&lt;p&gt;The 2021 event will be a little bit different than those in years past, as this event will be all virtual, hosted in late April 2021. We assure you that this will not be another multi-day webinar! We will do our best to make sure you have the best experience possible.&lt;br&gt;
**
What does that mean for attendees?&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>The DevOps Collective INC is pleased to announce the return of the PowerShell + DevOps Global Summit in April of 2021.</p><p>The 2021 event will be a little bit different than those in years past, as this event will be all virtual, hosted in late April 2021. We assure you that this will not be another multi-day webinar! We will do our best to make sure you have the best experience possible.<br>
**
What does that mean for attendees?</p><p>**<br>
Unfortunately, we do not currently have all the answers to your questions, but we are working diligently behind the scenes to iron out the details.  Here is what we do know so far:</p><ul><li>The event will have a paid attendee ticket. We are not a multibillion-dollar tech giant or a multimillion-dollar media company, so we can&rsquo;t offer the event for free. Believe us, we wish we could.</li><li>The videos will be available on-demand for all paid attendees. Videos will not be released for free until 9-12 months after the event.</li></ul><p>**
What does that mean for presenters?
**</p><ul><li>The CFP will open in the next week or two as we are still nailing down dates. Keep an eye out on<a href="https://powershellsummit.org">https://powershellsummit.org</a> for all the details as well as the official Twitter account of the event<a href="https://twitter.com/pshsummit">@pshsummit</a>.</li><li>Due to the event being all virtual:  Speakers will be required to record their videos and upload them to us a few weeks in advance (all the exact dates will be in the CFP).</li><li>Below are a few examples of the quality of recordings that are required. We are looking at possible speaker compensations as well. More details to come in the formal CFP announcement.<ul><li><a href="https://www.youtube.com/watch?v=z1butyGVxR8">https://www.youtube.com/watch?v=z1butyGVxR8</a></li><li><a href="https://youtu.be/y8SxQokIwiI">https://youtu.be/y8SxQokIwiI</a></li></ul></li></ul>
]]></content:encoded></item></channel></rss>