Important: take note of PowerShell is open sourced and is available on Linux | Blog | Microsoft Azure which is exciting news! This means we will soon be able to use PowerShell on Windows, Linux and Mac. Although we can use Bash on all three platforms too!


Possibly the best place to start from when new to PowerShell is PowerShell Documentation | Microsoft Docs, closely followed by Scripting with Windows PowerShell on Microsoft's website, which is a great launchpad for getting an introduction to PowerShell as well as digging deeper. There is some background information on PowerShell at Windows PowerShell - Wikipedia, the free encyclopedia which I have also found helpful.

It is important to note that "PowerShell Core" is the cross platform version of PowerShell and it is built on .NET core, you can get it from PowerShell/PowerShell: PowerShell for every system! and it can be installed on Windows alongside regular PowerShell, which is technically called "Windows PowerShell". This different between Windows PowerShell and PowerShell Core is explained at PowerShell 6.0 Roadmap: CoreCLR, Backwards Compatibility, and More! | PowerShell Team Blog. In addition Getting Started with PowerShell Core on Windows, Mac, and Linux | PowerShell Team Blog is a great article to help you get started with PowerShell Core.

When installing PowerShell on a Mac I would recommend using the Homebrew-Cask command:
brew cask install powershell which is fully explained at PowerShell/linux.md at master · PowerShell/PowerShell.

It is also worth noting that PowerShell has "Language Modes" where PowerShell can be placed into a restrictive mode for security reasons. This is to do with the security of the device PowerShell is running on and is designed to help prevent malicious attacks. See about_Language_Modes | Microsoft Docs.


If you want to know which version of PowerShell you are running then open an interactive PowerShell and type $PSVersionTable you can see from the list "PSVersion" which tells you which version you have and also "PSCompatibleVersions" which tells you which versions of PowerShell you have compatibility with.

If $PSVersionTable.PSEdition returns a null then it is an old version of PowerShell Windows, otherwise it will return "Core" or "Desktop" where Core means PowerShell Core and Desktop means full PowerShell Windows.

I have however noted that whilst my Windows 7 laptop and Windows Server 2012 R2 VM have the same PowerShell versions and "compatible versions" the available cmdlets are different. For example a lot of useful networking and IP related cmdlets like Get-NetIPAddress are only in Windows 8 or Server 2012 and above.


Should you happen to need PowerShell 2.0 for Windows XP then use the following link: Download Update for Windows XP (KB968930) from Official Microsoft Download Center, however I strongly recommend you stop using Windows XP as it stopped getting security updates in April 2014 and so is not safe to use. However there are variants of Windows XP in the embedded and retail space which are still being supported but not for long.


The best place to start is PowerShell Documentation | Microsoft Docs, from where you will find everything you need. Another good starting point is Windows PowerShell Core About Topics which is almost a language reference. There is also Windows PowerShell User's Guide probably a better pace for starting.

If there is a CmdLet you want help with then one easy way to get to the Microsoft documentation is as follows:
Get-Help Where-Object -Online
Clearly you can change "Where-Object" for any other Microsoft CmdLet. The "-Online" option basically launches your default web browser.

Sometimes the documentation you want is more along the lines of "What was that command again?", well there is help! You remember it was something to do with items, in which case try Get-Command *item* and you will get a list of all the CmdLets with the word "item" somewhere in their name, nice!


If you need to update PowerShell, so for example, you need PowerShell 4.0 on Windows Server 2008 R2 then How to Install Windows PowerShell 4.0 - TechNet Articles is a very useful article.

Best Practice

It is always good to adopt "best practice" or at least be consistent. Working off a common standard helps everyone. Having your code reviewed and checked is also a good thing. Thus it is well worth checking out PSScriptAnalyzer details on which you can find at PowerShell/PSScriptAnalyzer: Download ScriptAnalyzer from PowerShellGallery with more help and advice at PSScriptAnalyzer deep dive – Part 1 of 4 – Hey, Scripting Guy! Blog.

Useful Cmdlets

These cmdlets are ones I have used and found helpful, clearly there are many more:

  • Get-WinEvent - the preferred option for Windows Event Logs
  • Get-Date - for all things date but this is not a Timespan
  • Move-Item - great for move files, as well as other things like Registry entries
  • Remove-Item - will remove files, directories, registry keys etc
  • Start-Process - this is just brilliant
  • Start-Sleep - sleep or pause for a few milliseconds or seconds
  • Test-Path - returns true or false if the path exists, works with file, registry keys and more
  • Write-Host - for writing out to the console
  • Measure-Object - can count lines, words etc, however -Lines seems to ignore blank lines and lines of just whitespace, it can also process numbers and do this with CSV data too
  • Test-NetConnection - very handy for testing but only Windows 8/Server 2012 or higher, works with TCP and has a lot of diagnostic info
  • Test-Connection - very handy for testing, however it is ICMP based, note that it returns a lot more than it shows by default
For details on these and many other Cmdlets see Cmdlets which is a useful starting point. It is also worth being familiar with about_CommonParameters which applies to all Cmdlets.

Building on this, it is worth noting that when using Start-Process in a script called from IBM's Tivoli Workload Scheduler (TWS) I had to use -Wait, -RedirectStandardOutput and -NoNewWindow and then get the output file back in order to show the external process output on the console for TWS to pick up, skipping the redirect command caused some funny issues.

Handy Variables

There are a number of these but about_Automatic_Variables is a good place to find out about them.

Handy Constructs

These things have used and found helpful:

  • ForEach - work with items in an iterator
  • Switch - works as expected

Pausing and Keypresses

It seems that there are three options, a "read line" approach which requires the enter key to be pressed, a "detect key press" approach and a "message box" technique. None of them are especially hard. The simple "detect key press" is documented at Windows PowerShell Tip: Press Any Key to Continue and the "message box" is explained at Converting VBScript's MsgBox Function . The key press approach does not work from PowerShell ISE and so How to Properly Pause a PowerShell Script gives a more complete solution.

Windows Event Log

The easy way to parse, search or scan a Windows Event Log is to use the standard Event Viewer, which is either available standalone or via Computer Management. However you can also use PowerShell, which is much more flexible. The obvious cmdlet to use is Get-EventLog, however, whilst being good and flexible has a major issue, in that when working with a remote computer it drags everything local before filtering with Where-Object. So, the preferred cmdlet is Get-WinEvent which is harder to use but the investment is worth it, see Use PowerShell Cmdlet to Filter Event Log for Easy Parsing - Hey, Scripting Guy! Blog - Site Home - TechNet Blogs for more information on this.


My code editing tools of choice are Notepad++ and UltraEdit, and you will find more about them both on this website. However a "hard core" PowerShell scripting friend uses PowerGUI: Simplify your PowerShell and recommends it, so I am passing on his recommendation, because I respect his view, he said:

There are a couple of reasons why I like PowerGUI: You can single step through the script when testing/debugging. It has "Intellisense" style features that will offer the methods, variables and parameter names. Intellisense feature also works with SnapIns and Modules (SharePoint and Azure as an example) and once they have been run, any userdefined functions you have in the scripts.
So, well worth looking at!
Then there is Visual Studio of course, how could we miss that, so see Developing with VisualStudio for some details.

Random Stuff to Sort!

http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx - this documents the information available about files
http://technet.microsoft.com/en-us/library/dd347686.aspx - documentation on Get-ChildItem
PowerShell and Slack – Rambling Cookie Monster - using Slack from PowerShell

This is the starting point for several things PowerShell. The plan is to expand this over time but for now, if you need to get started then http://www.drdobbs.com/windows/powershell-for-developers-with-admin-tas/240150040 is a good place to start.

Also see the Regular Expression page for details for doing grep in PowerShell.

There is a nice script at Script PowerShell: Get Specific Files From Zip Files which is a good example of several things but primarily working with Zip files.

Desired State Configuration or DSC is supposed to be very good, note that Developers perspective on PowerShell Desired State Configuration – IndexOutOfRange is a good summary but is not an introduction or tutorial!

It is very easy to get PowerShell to generate HTML output and also not too hard to customise this output so it is easier to read, see Building HTML reports in PowerShell with ConvertTo-Html – 4sysops for details.

An interesting way to handle parameters, neatly: PowerShell splatting – 4sysops