Back in September, I had the pleasure of speaking at Microsoft Ignite. One of the topics I love talking and writing about is PowerShell. If you don’t know PowerShell then you really should consider learning the basics to help with your day-to-day tasks as an Office 365 administrator.
You can watch my session on the Microsoft Ignite YouTube channel.
On Practical 365 though, I wanted to talk you through not only what I shared in my quick 15-minute session, but to also explain a little more about the basics of PowerShell and how you can get started today.
PowerShell Basics
One of the great things about PowerShell is that it isn’t hard to understand the key concepts and re-use them again and again.
If we go back a few years – to command line scripting, VBScript or even Unix/Linux shells like Bash, then many people had good reason to fear the command line. In those environments, there simply isn’t a completely common standard for how things are done.
You might find one command or executable takes parameters one way (perhaps prefixed by a hyphen or a forward slash) yet another takes it a completely different way – in some cases command line tools present their own environment (like netsh, or ntdsutil). Understanding just how to get help on the command itself could be very complex. And in the case of VBScripts – you would be in the wild west. Some scripts might enforce parameters, some might even ask for user input when you run it, whilst others might not use any parameters at all.
PowerShell, however, works very differently. Once you understand how PowerShell commands (or cmdlets, to use their proper nomenclate) work, you can re-use that knowledge every time you use PowerShell.
The core of how PowerShell cmdlets work is based upon a Verb-Noun pair:
- The verb component is the part of the name that defines the action the command takes.
- The noun component is the part of the name that defines what the action will be performed against.
For example, most modules in PowerShell, like the Exchange Management Shell, have Get- cmdlets that retrieve information about components like Mailboxes, or Databases. They also have verbs corresponding to creating, updating, or deleting components too. This means you can create a New-Mailbox, update it with addition information using Set-Mailbox, and then get a list of all your mailboxes with Get-Mailbox.
Input to PowerShell is equally consistent. PowerShell cmdlets can accept parameters. These are added after the cmdlet, in any order you choose, and can be discovered easily using tab-based autocomplete. A parameter is in the form -Parameter followed by the data you want to provide. For example, if you want to retrieve information about a mailbox for one user, you will use Get-Mailbox -Identity steve@practical365.com.
Output from PowerShell is slightly more complex to understand, but you don’t need to know everything about how it works just to run cmdlets. Because PowerShell is object-oriented the output from a cmdlet isn’t purely text. Instead, the output is an object – which might be a list of objects, each of those containing attributes with information about each object. For example, when you retrieve a list of mailboxes, PowerShell’s built-in formatting might show it as a table in the command line, with just the most important information. However, the object contains all of the information the cmdlet has provided as output. Running Get-Mailbox for example will contain all the information about mailboxes that you’ll see if you examined the mailbox using the Exchange Admin Center and more.
Finally, you’ll need to know how to connect to Office 365 if you want to be able to manage it. You’ll find everything you need to know in our Office 365 Administration Portals and PowerShell Connections tutorial. Personally, I use MVP Michel De Rooij’s Connect to Office 365 script on my workstations to make it easy to connect to each service whenever I need to.
Useful cmdlets you need to know
After understanding the basics, it’s worth getting to know a few common cmdlets and combinations of commands that you can use. In no particular order, here are six that I use on a near daily basis.
Select-Object
When you use cmdlets like Get-Mailbox you’ll be presented with output filtered and formatted based on what the developers thought would be most useful to you. Sometimes though, you’ll just want specific information – especially if you want to export that to something like a CSV file for further examination.
Select-Object is perfect for this. Use the pipe | symbol after the cmdlet you’ve ran to pass the output object to Select-Object. Then enter the attribute names, followed by commas to select just those attributes:
Get-Mailbox | Select-Object DisplayName, PrimarySMTPAddress
Get-MailboxStatistics | Select-Object DisplayName,TotalItemSize
And if you aren’t sure about what attributes you could choose, just use Select * to select all attributes before you trim back on what is displayed.
Where-Object
When you use a cmdlet like Get-Mailbox without any parameters, you’ll receive a full list of all objects. With Get-Mailbox, that might be every mailbox. You might want to filter that by how an attribute is set. For example, you might want to search the output of Get-Mailbox for all mailboxes that are hidden from the address book. You can use Where-Object to accomplish this.
When you use the Where-Object cmdlet, every single line in the output object will be evaluated to determine if it matches the condition you set. You can use comparison operators like -eq or -like to evaluate where an attribute matches, is like, doesn’t match, is less than, or more than (and much more). Like we did with Select-Object we can specify the attributes to check. However, in the Where-Object cmdlet, we’ll prefix the attribute name with the special characters $_. as shown below:
Get-Mailbox | Where-Object {$_.HiddenFromAddressBook –eq $False}
Get-MsolDomain | Where-Object {$_.Authentication -eq "Federated"}
Foreach-Object
In my recent article Exporting Office 365 Group membership to a CSV file, I use the foreach loop to get specific information and add it to an exported CSV file. That’s just one example of many for how you can use the foreach loop. If you can’t just pipe the command from one to another, then the foreach loop allows you to access each line in the output object and run the same set of commands against each line. It’s a very simple technique and fundamental to all but the simplest of scripts:
Foreach-Object ($mailbox in (Get-Mailbox))
{
Get-MsolUser –UserPrincipalName $mailbox.userprincipalname
}
Start-Transcript.
Was it that command I ran last week? With Start-Transcript, you’ll be able to check what you did and perhaps notice that error you made – or perhaps prove that you didn’t make a mistake.
Start-Transcript starts a text-file transcript recording all the cmdlets (and text output) for your PowerShell session. You don’t even need to think about what to call the file. Whilst you can use the -Path parameter to specify the filename, if you just use the cmdlet without any parameters, it will create a new file in your Documents folder prefixed by PowerShell_transcript with the machine name and timestamp. When you’ve finished making changes, use Stop-Transcript to end logging:
Start-Transcript
# Do the thing that you were planning to do…
Stop-Transcript
# Next week, check the logs when you are asked to show them what you did
Export-CliXML.
Our penultimate cmdlet is one of the most useful tools to have in your PowerShell toolbelt if you are working with Office 365. Export-CliXML and it’s sister cmdlet Import-CliXML.
This pair of cmdlets allows us to capture the full output (including the hidden attributes we’ll use Select-Object above to display) to an XML file – a point of time capture of the state of Office 365.
In our example below, we can use the Get-Mailbox cmdlet to export everything the cmdlet would return to the Mailboxes.XML file. If we then, at a later date, use Import-CliXML to import the Mailboxes.XML file we can then treat it as if we were running Get-Mailbox over and over again. I’ll use this set of cmdlets day to day to capture information from an Office 365 tenant and then run scripts against that data without needing to access the tenant itself.
Get-MsolUser -All | Export-Clixml .\MsolUser.XML
Get-Mailbox –ResultSize Unlimited | Export-CliXML .\Mailboxes.XML
# Copy it somewhere else
Import-CliXML .\Mailboxes.XML
Get-Help.
Finally, it’s the most useful cmdlet you’ll have in your PowerShell toolbox, Get-Help. If you haven’t used a cmdlet for a while, or it’s perhaps your first time, then Get-Help provides detailed information about how to use the cmdlet and often examples of how to use it. In the example below, you’ll see my most useful parameter for Get-Help, -Examples – I will use this to remind me of now only which are the key parameters to use, but what typical parameter values might be. –Detailed provides more information about the cmdlet, including detailed information about each parameter, whilst –Online is commonly available for Microsoft cmdlets and redirects us to the Microsoft Docs version of the cmdlet documentation.
Get-Help Get-MsolAdministrativeUnit –Examples
Get-Help Get-MsolAdministrativeUnit –Detailed
Get-Help Get-SPOTenant -Online
What to do next
If you aren’t using PowerShell today, then check out our dedicated PowerShell section to learn a little more.
If you want to get started with these example, then consider doing the following…
- Pick some Get- commands you think might be useful and use Get-Help to understand more about them. Can’t find any? Try Get-Command
- Use Start-Transcript and Export-CliXML to keep a copy of how things were before and after and a log of what you did
- Use Select-Object in combination with Export-CSV or Out-gridview to make it easy for the you to provide reports from commands or view it on screen.
- Use Where-Object and Foreach-Object to automate your first task!
Really appreciate for this.
Great tips. Thanks.
I’m beginner for powershell. It will be helpful me.
Cool thanks! .