Powering Up With PowerShell: Article 1 – The Basics
Getting started with PowerShell
While there are many languages, PowerShell is the primary scripting language supported by Microsoft for Windows and Azure administration and automation as well as widely supported by the Linux world. In this article we will be going over many of the features of PowerShell, while skipping much of the boring fluff to get you started with PowerShell scripting quickly. We will be utilizing Visual Studio Code for our scripting in these articles.
Installing PowerShell and Visual Studio Code
- Installing PowerShell
- PowerShell comes pre-installed on the latest versions of Windows, but just in case I have linked installation instructions and the download page below.
- Installing PowerShell – PowerShell | Microsoft Docs
- Release v7.1.4 Release of PowerShell · PowerShell/PowerShell · GitHub
- Visual Studio Code
- Visual Studio Code – Code Editing. Redefined
- Quick Installer (Ninite) – Ninite Visual Studio Code Unattended Silent Installer and Updater
- Visual Studio Code Extensions
- PowerShell – PowerShell – Visual Studio Marketplace
- From within Visual Studio Code:
- Select the Extensions button on the left
- Search for the above modules
- Select the module name
- Select Install
- From within Visual Studio Code:
- PowerShell – PowerShell – Visual Studio Marketplace
Github Repo for this article
Terms
Lets touch on some basic terms that will be used going forward
- Function
- Specific segment of PowerShell code that is intended to do one action. Functions allow you to create your own PowerShell commands that can be issued manually or programmatically. Functions can accept input parameters or variables as well as return data.
- Module
- Packaged set of related PowerShell commands and scripts.
- Parameter
- Represented by a $ . Parameters are inputs that functions and scripts rely on to execute their actions.
- Pipeline
- Represented by a | . Pipelines are methods that allow you to pass objects from one command into another.
- Scope
- PowerShell protects access to variables, functions, and scripts by limiting how and where they can be read and changed. There are three scopes:
- Global
- The default overarching scope that is in effect when PowerShell starts or when you create a new session.
- Local
- The current Local can be the global or any other scope.
- Script
- The scope that is created while a script runs. Only commands in the script run within the script scope. To commands within a script, the script scope is the local scope.
- Script
- A PowerShell script is a simple text file with a .ps1 extension that can be executed.
- Variable
- Represented by a $ . Variables are memory placeholders in which values are stored. Variables are incredibly dynamic and can hold many different types of values.
- Global
- PowerShell protects access to variables, functions, and scripts by limiting how and where they can be read and changed. There are three scopes:
Comments
All coding languages have a format for inputting text in the code that will not be executed and merely acts as documentation of what the code is doing. In PowerShell this operator is #, so any text following a # will not execute, we will be utilizing this heavily in this article to explain the code below. Always be sure to comment your code efficiently as to document what is going on for future programmers who may use your code.
IntelliSense
When writing script, you can utilize what is known as IntelliSense to auto-fill commands and parameters.
In Visual Studio Code and Windows PowerShell, the hotkey to utilize IntelliSense is CTRL+Spacebar. You will be prompted with the possible commands that will finish what you had started typing and have the ability to navigate these options with the arrow keys and can select one with the enter key.
Verbs & Nouns
PowerShell has standardized formatting for how commands and functions are named based around the concept of approved verbs and nouns. To get a full list of possible approved verbs for PowerShell modules you can run the command Get-Verb. The syntax for most all PowerShell commands is Verb-Noun.
# To list all possible verbs Get-Verb
You can find approved Verbs and proper usage here: Approved Verbs for PowerShell Commands – PowerShell | Microsoft Docs
Github link to Verbs, Commands, and Parameters sample script
Commands
PowerShell has a huge number of modules that can be installed, you can get a list of possible commands you can run with the Get-Command command.
# To list all commands Get-Command # To list commands filtered by a verb Get-Command -Verb ‘Get’ # To list commands filters by a noun Get-Command -Noun A* # To list commands filtered by both a verb and a noun Get-Command -Verb Get -Noun A*
PowerShell Gallery is the site to go to find modules to install
Github link to Verbs, Commands, and Parameters sample script
Parameters
Most commands will have optional and required parameters that need to be fed into them for them to function as expected. The syntax for this will be Verb-Noun -Parameter Value.
# To list commands filters by a noun Get-Command -Noun A*
Github link to Verbs, Commands, and Parameters sample script
1 – Variables
Loading data into variables is the most common way to work with data in a script. Variables can be text, numbers, hastables, arrays, objects, and more. Variables can even have arithmetic operations performed against them. Below we will perform some basic addition of numbers and text variables and display the results with an echo command.
Text and Integers
# Number variables being added $Variable1 = 2 $Variable2 = 2 $Variable3 = $Variable1 + $Variable2 echo $Variable3 4
# Text variables being added together
$Variable1 = "Rivia" $Variable2 = ".io" $Variable3 = $Variable1 + $Variable2 echo $Variable3Rivia.io
Github link to Variables, Arrays, HashTables, and Objects section sample script
Arrays
Arrays are nothing more than a list of data that can be accessed separately.
### Arrays # Create empty array (Note Arrays use () brackets while HashTables use {}) $Array1 = @() # Count how many values in the array $Array1.count 0 # Create Array with data $Array2 = @(0,1,2,3,4,5) # Display Array echo $Array2 0 1 2 3 4 5 # Count how many values in the array $Array2.count 6 # Other ways of creating Arrays $Array3 = 'Zero','One','Two','Three' echo $Array3 Zero One Two Three # Retrieve specific point of data from an array (Starts at 0 and counts up) $Array3[1] One # Retrieve specific point of data from an array in reverse $Array3[-1] Three # Retrieve multiple points of data from the array $Array3[0,3,1] Zero Three One # Retrieve all data between two points $Array3[0..3] Zero One Two Three # Retrieve all data between two points in reverse $Array3[3..0] Three Two One Zero # Update an item in an array $Array3[1] = 'Uno' echo $Array3[1] Uno
Github link to Variables, Arrays, HashTables, and Objects section sample script
Hash Tables
When loading objects into a variable with multiple properties, those additional properties can be referenced directly by following the format of $VariableName.PropertyName. We will explore property names utilizing a Hash Table below. A Hash Table, also known as a dictionary or associative array, is a compact data structure that stores one or more key/value pairs. This allows you to store information within a single object in an organized fashion.
### Hash Tables # Create empty HashTableAgeList variable (Note HashTableAgeLists use {} brackets while Arrays use {}) $HashTableAgeList = @{} echo $HashTableAgeList # Create HashTableAgeList with pre-defined values $HashTableAgeList = @{"John Doe" = 26; "Jane Doe" = 24} echo $HashTableAgeList Name                          Value ----                          ----- Jane Doe                      24 John Doe                      26 # Count of how many key pairs are in the HashTable $HashTableAgeList.Count 2 # Display the value for a specific key, in this case showing the age of the referenced name $HashTableAgeList['John Doe'] 26 # Display the value for a multiple keys, in this case showing the age of the referenced names $HashTableAgeList['John Doe','Jane Doe'] 26 24 # Add value to HashTableAgeList $HashTableAgeList.add('Sam Smith' ,32) echo $HashTableAgeList Name                          Value ----                          ----- John Doe                      26 Sam Smith                     32 Jane Doe                      24 # Remove value to HashTable $HashTableAgeList.remove('John Doe') echo $HashTableAgeList Name                          Value ----                          ----- Sam Smith                     32 Jane Doe                      24
Github link to Variables, Arrays, HashTables, and Objects section sample script
Custom Object
Unlike an array or Hashtable, Objects are intended to represent a singular entity rather than multiple entities or lists. You create an object the same way you would create a Hashtable, however you add the [PSCustomObject] before the @ symbol.
### Custom Objects # Create Custom Object, unlike arrays or hashtables objects represent a single entity $Object = [PSCustomObject]@{     Name = 'Jane Doe'     Age = 29     State = 'CA'     ZipCode = 94102 } # Display entire object as a default table echo $Object Name    Age State ZipCode ----    --- ----- ------- Jane Doe 29 CA     94102 # Display entire object as a list echo $Object | Format-List Name   : Jane Doe Age    : 29 State  : CA ZipCode : 94102 # Display specific value echo $Object.Name Jane Doe # Add properties to Object $Object | Add-Member -MemberType NoteProperty -name 'Gender' -Value 'F' echo @Object Name   : Jane Doe Age    : 29 State  : CA ZipCode : 94102 Gender : F
Github link to Variables, Arrays, HashTables, and Objects section sample script
2 – Piping
One of the most powerful features of PowerShell is called piping. Piping allows you to pass the results from one command directly into another. For this example we will be exploring what we can do with the Get-Process command utilizing some piping functionality. In order to pipe an action you simply use the | Â operator, actions will be piped from the left most command to the right most in order. When piping, the output data is represented by a placeholder variable known as $_ unless specified previously.
# List all processes on machine running the script Get-Process Handles NPM(K)   PM(K)     WS(K)    CPU(s)    Id SI ProcessName ------- ------   -----     -----    ------    -- -- -----------    397     30   24072     36604      0.42 27088  2 AcrobatNotificationClient    347     25   10240     23224      0.45 20920  2 acrotray    304     21    9412     16644      0.27  5132  2 AdobeCollabSync    547     30   13976     25696     33.80 13604  2 AdobeCollabSync    407     29   23552     10908      0.53 14172  2 AdobeNotificationClient    ***     **   *****     *****      **** *****  * ***************    ***     **   *****     *****      **** *****  * *************** # Get all processes starting with the Power Get-Process | Where-Object {$_.ProcessName -like "Power*"} Handles NPM(K)   PM(K)     WS(K)    CPU(s)    Id SI ProcessName ------- ------   -----     -----    ------    -- -- -----------    549     32   84508     77408     24.02  7392  2 powershell    609     33   78444     80088      1.95 28860  2 powershell  1212     70  174520    173440     20.56 33080  2 powershell # List all properties and methods available for the command Get-Process Get-Process | Get-Member TypeName: System.Diagnostics.Process Name                      MemberType    Definition ----                      ----------    ---------- Handles                   AliasProperty Handles = Handlecount Name                      AliasProperty Name = ProcessName NPM                       AliasProperty NPM = NonpagedSystemMemorySize64 PM                        AliasProperty PM = PagedMemorySize64 SI                        AliasProperty SI = SessionId VM                        AliasProperty VM = VirtualMemorySize64 WS                        AliasProperty WS = WorkingSet64 Disposed                  Event         System.EventHandler Disposed(System.Object, System.EventArgs) ErrorDataReceived         Event         System.Diagnostics.DataReceivedEventHandler ErrorDataReceived(System.Object, System.Diagnostics.DataReceivedEventArgs) Exited                    Event         System.EventHandler Exited(System.Object, System.EventArgs) OutputDataReceived        Event         System.Diagnostics.DataReceivedEventHandler OutputDataReceived(System.Object, System.Diagnostics.DataReceivedEventArgs) BeginErrorReadLine        Method        void BeginErrorReadLine() BeginOutputReadLine       Method        void BeginOutputReadLine() CancelErrorRead           Method        void CancelErrorRead() CancelOutputRead          Method        void CancelOutputRead() ****************          ******        ***************************** # List the first 3 properties and methods available for the command Get-Process Get-Process | Get-Member | Select-Object -First 3 TypeName: System.Diagnostics.Process Name   MemberType   Definition ----   ----------   ---------- Handles AliasProperty Handles = Handlecount Name   AliasProperty Name = ProcessName NPM    AliasProperty NPM = NonpagedSystemMemorySize64
Github link to Piping section sample script
3 – Splatting
To keep things neat and concise for large scripts, splatting can come in handy. Splatting is a method that allows you to take a Hashtable or Array and pass it as a commands parameters. Splatting makes your commands much shorter and easier to read. To splat a command, simply create a Hashtable or Array variable and use that variable with the @ symbol rather than the typical $ symbol.
### Splatting # Set variable for new file $FilePath1 = 'c:\Rivia\File.txt' $FilePath2 = 'c:\Rivia\File2.txt' $UpdateFileArguments = @{     Path = "$FilePath1"     Value = "This text will be input into the file"   } # Create new text file New-Item $FilePath1 Directory: C:\Rivia Mode                LastWriteTime       Length ----                -------------       ------ -a----        9/12/2021  2:39 PM            0 # Set variable for content of File1 from the splatted arguments Set-Content @UpdateFileArguments # Read from the created file Get-Content $FilePath1 This text will be input into the file # Create Hashtable for command arguments $CopyFileArguments = @{     Path = "$FilePath1"     Destination = "$FilePath2"     WhatIf = $false   } # Copy file with the splatted arguments Copy-Item @CopyFileArguments # Read from the copied file Get-Content $FilePath2 This text will be input into the file
Github link to Splatting section sample script
Summary
We are just getting warmed up with PowerShell, in this article we looked at:
- How to get PowerShell and Visual Studio installed
- Verbs and Nouns
- Command structure and how to find commands
- Parameter basics
- Variable types and basics on how to utilize them
- Piping of commands
- Parameter splatting
Â
Â
Responses