Code Snippets

Hide Output

Some commands default to giving output to the console, New-Item for example does this. However it is not hard to suppress this as in the following example:
New-Item -ItemType Directory "C:\Temp\NewFolder" | Out-Null

Read File

There seems to be one standard, reliable approach, which is as follows: $content = [IO.File]::ReadAllText(".\test.txt"), this works well, however in PowerShell 3 and above you can use $text = Get-Content .\file.txt -Raw . Note that without the -Raw you will get an array of lines.

Environment Variables

I suggest you just read Windows PowerShell Tip: Creating and Modifying Environment Variables not much value I can add to that! However, if you want to get the value of the logonserver environment variable you can do this with $Env:logonserver, which is nice and easy.

Loops

There are a number of options when looping: For, ForEach, While, Do...While, Do...Until, these are all described at PowerShell Loops - TechNet Articles - United States (English) - TechNet Wiki. However, if you want to exit a loop "early" then use Break.

Some examples:
$array = 1,2,3,4,5
ForEach ($value in $array) {
    Write-Host "Value: $($value)"
}
For ($i; $i-lt5; $i++) {
    Write-Host $i
}

I have also used ForEach with collections.

Switch and If

You will probably need to read about_Comparison_Operators and about_Logical_Operators if you are using if statements.

Great to see switch working on strings! For examples of using If, see Hey, Scripting Guy! How Can I Use the If Statement in Windows PowerShell? - Hey, Scripting Guy! Blog - Site Home - TechNet Blogs

Booleans

The key point to note is that $TRUE and $FALSE represent True and False but see Boolean Values and Operators - Windows PowerShell Blog - Site Home - MSDN Blogs and Understanding Booleans in PowerShell - TechNet Articles - TechNet Wiki for more details. However for comparisons etc see about_Comparison_Operators and also see about_Logical_Operators.

Temporary File

Here is a nice little example of working with a temporary file:
 
$TmpFile = [System.IO.Path]::GetTempFileName()
Get-ChildItem $TmpFile # Same as ls
Remove-Item $TmpFile
ls $TmpFile

Script Directory

Sometimes you need to know the directory your script file is located in, especially if it is not the current directory. This is easily done with $MyInvocation.MyCommand.Path, well that gets the filename as well, doing Split-Path $MyInvocation.MyCommand.Path will get you just the directory. In PowerShell 2 and above you can use $PSScriptRoot, however it only works in script modules (.psm1) but in PowerShell 3 it works in regular scripts as well.

Launch Child Process

This is quite easily done with Start-Process, however you do have to learn the different paramters that go with this, for example -Wait, -NoNewWindow -RedirectStandardOutput -RedirectStandardError -ArgumentList -PassThru.

It is -PassThru, I want to give an example of:
$Result = Start-Process "CScript" -PassThru -Wait -NoNewWindow -RedirectStandardOutput $OUTPUT_FILE -RedirectStandardError $OUTPUT_ERR_FILE -ArgumentList ".\VBScript.vbs arg1 arg2"
 
if ($Result) # This actually means "if not null"
{
  Write-Host $Result.GetType().FullName
  Write-Host $Result.ExitCode
}

Defining Variables

You can define a variable in two different ways, as follows:
$var1 = 100
Set-Variable var2 200

In both these cases the values are changeable. You can make a variable read-only like this:
Set-Variable -Option ReadOnly var3 300
Then if you try to change the value you get an exception. However you can delete the variable and re-create it, although removing requires the use of the "force" option as seen in the folloing example:
Remove-Variable -Force var3
If you want to create a real constant that cannot be changed or remove, even with a force, then you need this:
Set-Variable -Option Constant var4 400
Set-Variable -Option Constant -Name var4 -Value 400

Type Information

To display full type information of a variable use one of the following:
$var.GetType()
$var.GetType().FullName
Where the first gives you all the type iformation and the second the complete type name, which is useful for testing for a type, which is done as follows:
if ($var -is [System.DateTime]) ...

Null

This is one of those sometimes useful programming constructs and other times troublesome. If you want a null, then in PowerShell you can use $null.

PowerShell Versions

Example code for getting the versions:
Write-Host "PowerShell Version: $($PSVersionTable.PSVersion)"
Write-Host "Compatible Versions: $($PSVersionTable.PSCompatibleVersions)"
ForEach ($version in $PSVersionTable.PSCompatibleVersions) {
    Write-Host "-Version: $version"
}

Runtime

There are plenty of interesting options documented at Environment Class (System), however the following code has proved useful:
Write-Host "Is this 64-bit PowerShell? $([Environment]::Is64BitProcess)"
It is worth reading the link and seeing what else you can do.

Adding Users to Groups

This is a handy but simple code example that adds a domain user account to a group on the local machine. This is handy when the visual Computer Management tools are not available or you are running Server Core. To add the user account "john.smith" from the "CORP" domain into the local computer's Power Users group execute the following line of PowerShell:
([ADSI]"WinNT://$env:computername/Power Users,group").Invoke('Add', "WinNT://CORP/john.smith")
You can clearly wrap this into a function and get user input at runtime etc but this is the basic.

By way of reference the above is the same as the following:
net localgroup "Power Users" /ADD CORP\john.smith

Sending E-Mail

The key is using Send-MailMessage, however I would recommend also using Get-Credential to control the message displayed to the user.

String Splitting

One approach is to find the position of the separator and then get the text before and after it, as follows:

$text = "One,Two,Three;Four;Five-Six"
$pos = $text.IndexOf(";")
$leftPart = $text.SubString(0, $pos)
$rightPart = $text.SubString($pos+1)
This results in $leftPart having the text "One,Two,Three" and $rightPart having the text "Four;Five-Six". This technique is nice and simple and clear, however it really only works with one separator and two parts.

The second approach, which gives the same output is $text.Split(";", 2), however this returns an array, so the left part is $text.Split(";", 2)[0] and the right part is $text.Split(";", 2)[1], note that the number 2 specifies a maximum of two parts. If you leave the number off then every semi-colon is treated as a separator. Furthermore if you use $text.Split(",;-") then all three of those characters are used as separators and 6 items are returned, each one containing a word.

Counting Lines

You can use the Measure-Object cmdlet for this, as follows:
dir -Recurse *.txt | Get-Content | Measure-Object -Line
However, I have noticed it does not count blank lines or lines that are just whitespace.