Blog   ❯   Author: Fabio MoschiniDate: 27.11.2022

Introduction to PowerShell

alt text for image

What is PowerShell

PowerShell is a command-line tool (CLI) for configuring and automating the operating system, its components and other technologies such as SQL Server, Exchange, AWS and Google Cloud.
It is cross-platform: available for Windows, Linux and macOS.
In this article we will see some practical PowerShell examples.

Local computer information

Let's see some commands to retrieve information about the local computer.
We start with a command that shows BIOS information:
Get-CimInstance -ClassName Win32_BIOS
The command output is:
SMBIOSBIOSVersion : 7.004
Manufacturer      : American Megatrends Inc.
Name              : 7.004
SerialNumber      : Not Applicable
Version           : ALASKA - 1072009

You can view processor information via the WMI class Win32_Processor:
Get-CimInstance -ClassName Win32_Processor
The output is:
DeviceID Name                                         Caption                                    MaxClockSpeed SocketDesignation Manufacturer
-------- ----                                         -------                                    ------------- ----------------- ------------
CPU0     Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz     Intel64 Family 6 Model 158 Stepping 10     2201          U3E               GenuineIntel

To get the computer model information, run this command:
Get-CimInstance -ClassName Win32_ComputerSystem

In addition, you can get operating system information via:
Get-CimInstance -ClassName Win32_OperatingSystem

To view available space on local disks:
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
whose output is:
DeviceID DriveType ProviderName VolumeName   Size          FreeSpace
-------- --------- ------------ ----------   ----          ---------
C:       3                                   510718373888  58673197056
D:       3                      Volume       2000381014016 677303054336
G:       3                      Google Drive 16106127360   14858432512

The option -Filter "DriveType=3" is used to list only data related to hard disks, excluding, for example, SD cards.

To display the current local time:
Get-CimInstance -ClassName Win32_LocalTime
which produces this output:
Day            : 12
DayOfWeek      : 6
Hour           : 15
Milliseconds   :
Minute         : 3
Month          : 11
Quarter        : 4
Second         : 41
WeekInMonth    : 2
Year           : 2022
PSComputerName :

File system operations

In this section we will see how to manage some file system related tasks using PowerShell.

List files and directories inside a directory

Get-ChildItem -Path C:Test -Force -Recurse
The -Path parameter, followed by the directory name, defines the path whose contents to display. The -Forceparameter shows hidden and system files. The -Recurseparameter allows listing files and directories at deeper levels. You can filter the list of files to display.

For example, to see only files with a certain extension you can use this command:
Get-ChildItem -Path C:Test -Include *.js
If we wanted to sort files by name, we could use this command:
Get-ChildItem -Path C:Test -Include *.js | sort name
In this case the sorting is ascending.
To force descending sort, specify -Descending:
Get-ChildItem -Path C:Test -Include *.js | sort name -Descending

Copy files or directories

To copy a file use:
Copy-Item -Path C:Test\readme.txt -Destination C:Test\readme.bak
If the destination file already exists, you can overwrite it by specifying -Force:
Copy-Item -Path C:Test\readme.txt -Destination C:Test\readme.bak -Force
The command for copying a directory follows a similar syntax:
Copy-Item -Path C:Test\subdir -Destination C:Test\subdir_new -Recurse
You can specify which files to copy from one folder to another by using the -Filter parameter, for example:
Copy-Item -Filter *.txt -Path C:Test\subdir -Destination C:Test\subdir_new -Recurse

Create files or directories

To create a new directory use:
New-Item -Path C:Test\NuovaDir -ItemType Directory
Similarly, to create a new file use:
New-Item -Path C:Test\NuovaDir\NuovoFile.txt -ItemType File
The created file will, of course, be empty.

Delete files or directories

To delete a directory with all its contents, use:
Remove-Item -Path C:TestNuovaDir
If the directory to delete, the command execution will ask for confirmation. To avoid this prompt, use the -Recurseparameter:
Remove-Item -Path C:TestNuovaDir -Recurse
Remove-Item -Path C:TestNuovoFile.txt

Operations on Sql Server

As mentioned, PowerShell can perform operations on a Sql Server instance. For example, we can run a SQL script that creates a table:
$SQLServer = "<<Nome Istanza SQL Server>>" $db = "<<Database>>" $createtable = "CREATE TABLE TabellaTest (Id TINYINT, Descr VARCHAR(50))" Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db -Query $createtable
After creating the table, we insert some data:
$SQLServer = "<<Nome Istanza SQL Server>>" $db = "<<Database>>" $insertdata = "INSERT INTO TabellaTest VALUES (1,'Alfa'), (2,'Beta'), (3,'Gamma'), (4,'Delta'),(5,'Epsilon')" Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db -Query $insertdata
At this point we can read data from the table:
$SQLServer = "<<Nome Istanza SQL Server>>" $db = "<<Database>>" $selectdata = "SELECT * FROM TabellaTest" Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db -Query $selectdata
As you can easily imagine, we can also run UPDATE and DELETE commands:
$SQLServer = "<<Nome Istanza SQL Server>>" $db = "<<Database>>" $updatedata = "UPDATE TabellaTest SET Descr = 'Delta new' WHERE Id = 4" Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db -Query $updatedata $deletedata = "DELETE FROM TabellaTest WHERE Id = 5" Invoke-Sqlcmd -ServerInstance $SQLServer -Database $db -Query $deletedata

Conditional execution

As in traditional languages, PowerShell scripts can use conditional statements such as IF:
$condizione = $true if ( $condizione ) { Write-Output "La condizione è vera" }
or in the form that includes else:
$condizione = $true if ( $condizione ) { Write-Output "La condizione è vera" } else { Write-Output "La condizione è false" }
To perform multiple comparisons between a variable and its possible values you can use the switch statement:
$language = 'PowerShell' switch ( $language ) { 'C#' { 'Il linguaggio è C#' } 'PowerShell' { 'Il linguaggio è PowerShell' } 'SQL' { 'Il linguaggio è SQL' } }
The condition can be an expression containing comparison operators.
For example, the equality operator is -eq (case-insensitive) or -ceq (case-sensitive).
The inequality operator is -ne (case- insensitive) or -cne (case-sensitive).
If you need to compare values using "greater than..." or "less than..." operators, you can use:
-gt: greater than... (case-insensitive)
-cgt: greater than... (case-sensitive)
-ge: greater than or equal to... (case- insensitive)
-cge: greater than or equal to... (case- sensitive)
-lt: less than... (case-insensitive)
-clt: less than... (case-sensitive)
-le: less than or equal to... (case- insensitive)
-cle: less than or equal to... (case- sensitive)

Logical operators are also available. For example:
-not or !: the negation operator
-and: logical AND operator
-or: logical OR operator

Loop

There are several types of loops in PowerShell.

ForEach-Object
Using ForEach-Object you can loop through all elements of an object.
For example, to list all files in the directory "c:mydir"you could use this script:
$myDocuments = Get-ChildItem c:mydir -File $myDocuments | ForEach-Object {$_.FullName}
or:
$myDocuments = Get-ChildItem c:mydir -File ForEach-Object -InputObject $myDocuments -Process {$_.FullName}
The $_ variable represents the current object inside the loop.
The -Process parameter specifies the operation to execute on each element of the object.

For
The For loop can be used to iterate within a range defined by a minimum and maximum value.
For example, to print multiplication tables we can use this script:
For ($t=1; $t -le 10; $t++) { "Tabellina del " + $t For ($i=1; $i -le 10; $i++) { "$t * $i = " + ($t * $i) } }
You can also use the For loop to iterate over array elements:
$colori = @("Rosso","Blu","Verde","Giallo","Rosa","Bianco","Nero") For ($i=0; $i -lt $colori.Length; $i++) { $colori[$i] }

While, Do-While, Do-Until
The third type of loop supported by PowerShell is characterized byWhile, Do-While, Do-Until.
In this case the loop continues as long as a certain condition is true or false.
While and Do-While are used to execute an action when the condition is true.
Do-Until has a syntax similar to Do-While, with the difference that the loop runs while the condition is false and ends when the condition becomes true.
For example, to print integers from 1 to 10 you can use this script:
$i=1 Do { $i $i++ } While ($i -le 10)
or:
$i=1 Do { $i $i++ } Until ($i -gt 10)
or:
$i=1 While ($i -le 10) { $i $i++ }
To exit a loop when a certain condition occurs, use the Breakkeyword:
$i=1 While ($true) { $i $i++ if ($i -gt 10) { Break } }

Functions

In PowerShell you can define and call two types of functions:
  • - without parameters
  • - with parameters
function nomeFunzione {codice}
To call the function, simply use its name:
nomeFunzione
Example: script that defines a function to display the current date:
function displayDate { Get - Date } displayDate
For functions with parameters you can choose between two syntaxes:
- the first syntax allows defining named parameters and uses the keyword param. Example:
function dividiValori() { Param ([int]$a,[int]$b) $quoziente = $a / $b return $quoziente }
The function dividiValori can be called like this:
dividiValori -a 10 -b 2
or like this:
dividiValori -b 2 -a 10
or without naming the parameters but providing the values separated by a space:
dividiValori 10 2
yielding the same result, since in the first two cases parameters are passed by name while in the third case values are passed by position.

- the second syntax does not use the paramkeyword but allows declaring parameters immediately after the function name:
function moltiplicaValori([int]$x,[int]$y) { $prodotto = $x * $y return $prodotto }
With this syntax parameters are also passed by name, so the following calls:
moltiplicaValori -x 3 -y 5 moltiplicaValori -y 5 -x 3 moltiplicaValori 3 5
return the same result.
You can call a function recursively.
For example, you could define a factorial function like this:
function fattoriale([int]$numero) { if($numero -lt 0) { $risultato = 0 } elseif($numero -le 1) { $risultato = 1 } else { $risultato = $numero * (fattoriale($numero - 1)) } return $risultato } fattoriale 5

Error handling

To catch errors that may occur during script execution we can use theTry/Catch construct.

Example:
try{ Questa istruzione non è permessa "Questo è permesso" } catch{ Write-Host "Si è verificato un errore." -BackgroundColor DarkRed }
As you can easily imagine, the line containing"Questa istruzione non è permessa" generates an error during script execution because the command is not valid.
When the error occurs execution passes to the catchblock where the warning is displayed on a red background.
You can specify an optional Finally block that will execute regardless of whether an error occurred.
try{ Istruzione non permessa "Questo è permesso" } catch{ Write-Host "Si e' verificato un errore." -BackgroundColor DarkRed Write-Host "Riga: " $Error[0].InvocationInfo.ScriptLineNumber Write-Host "Codice: " $Error[0].InvocationInfo.Line Write-Host "Rilevato in: " $Error[0].InvocationInfo.PositionMessage } finally{ Write-Host "Il blocco 'finally' viene sempre eseguito." -BackgroundColor Green -ForegroundColor Black }
In the catch block we used the $Error object to display additional information about the error cause.
The properties of the $Error object can be listed with:
$Error | Get-Member | Select Name, MemberType
The returned output is:
|Name                    |MemberType
|----                    |----------
|Equals                  |Method
|GetHashCode             |Method
|GetObjectData           |Method
|GetType                 |Method
|ToString                |Method
|CategoryInfo            |Property
|ErrorDetails            |Property
|Exception               |Property
|FullyQualifiedErrorId   |Property
|InvocationInfo          |Property
|PipelineIterationInfo   |Property
|ScriptStackTrace        |Property
|TargetObject            |Property
|PSMessageDetails        |ScriptProperty