Output your ForEach into a file

Something that i always forget after spending a little while perfecting the contents of your ForEach loop is that eventually it’ll be necessary to output the content as Objects or into a file of some sort, whether thats before or after some manipulation. The answer to this is a very simple one, you need to store your ForEach in a variable and then reference that Output at the end of the ForEach scriptblock, like below:

$process = Get-Process

$output = foreach($line in $process){

Write-Output $line | select Handles, Id, ProcessName


$output | Sort-Object -Property ProcessName | ft

The $output variable will now contain the objects in your ForEach and you can do whatever you want with them.

Get Exchange 2013 Database and Whitespace values.

In organisations that are still using Exchange 2013, you may want to be able to differentiate between the actual size of your databases and the whitespace provisioned for your databases to use.

The below PowerShell script can be added as a Scheduled Task in order to notify your Infrastructure teams.

# This script will take the database sizes from exchange and email them to a mail address.
# First we import the exchange module.

$ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<SMTPServer>/PowerShell
Import-PSSession $ExchangeSession

# Creating our array to allow string and output of command into subject.
$string = “<Org> Database Sizes – ”
$Date = (Get-Date)
$SMTPSubject =  $string + $date

# Factor in the variables for the Send-MailMessage command.

$SMTPTo = “emailrecipient@domain”
$SMTPFrom = “emailsender@domain”
$SMTPServer = “<SMTPServer>”
$SmtpBody = Get-MailboxDatabase -Status | select name, databasesize, AvailableNewMailboxSpace | Sort-Object Name | Out-String

# Then output that into a mail message.

Send-MailMessage -SmtpServer $SMTPServer -From $SMTPFrom -To $SMTPTo -Body $SmtpBody -subject $SMTPSubject

Azure IaaS Patching

When on a customer site recently, one requirement the customer was looking to achieve was to incorporate their IaaS virtual machines into their monthly patching policy. Their Iaas VM’s were shutdown nightly and all day on a weekend by a runbook.

This can be done with a relatively simple PowerShell script split into two functions; Start-AzurePatching and Stop-AzurePatching. The logic of the Start-AzurePatching function is as follows:

  • Connect into Azure PowerShell and choose the subscription you want to work with.
  • First the script will aggregate the VM properties inside each resource group.
  • The runbook being used to shut down your VM’s is looking to interact with a Tag named “AutoShutdownSchedule”
  • If it finds any VM with the tag “AutoShutdownSchedule”  it will remove it, replacing it with one that will allow it to start on a Saturday.
  • The new tags will be set against the virtual machine
  • The VM’s will be started.

The logic of the Stop-AzurePatching is similar:

  • The script will again aggregate all the VM’s settings, specifically looking for VM’s with the “AutoShutdownSchedule” tag.
  • The tag set by Start-AzurePatching will be replaced with a tag that includes the original shutdown settings, meaning the VM’s will be shutdown on a saturday and sunday.
  • The new tags will then be applied to the VM’s.

There isn’t a need to then shut the machines down via this script, as the runbook upon its next cycle will identify these machines as being VM’s that should be offline, and shut them down for you.

Azure Patching PowerShell script.

Function Start-AzurePatching {

$subId = ( Get-AzureRmSubscription |
Out-GridView `
-Title “Select an Azure Subscription” -OutputMode Single
Select-AzureRmSubscription -SubscriptionId $subId

foreach($AzureRmVm in (Get-AzureRmResourceGroup | Get-AzureRmVm))
if($AzureRmVm.Tags.Keys -like “*AutoShutdownSchedule*”)
$AzureRmVm.Tags.Remove(‘AutoShutdownSchedule’) | Out-Null
$AzureRmVm.Tags.Add(‘AutoShutdownSchedule’,’8PM -> 5AM, Sunday, December 25′) | Out-Null

Set-AzureRmResource -ResourceGroupName $AzureRmVm.ResourceGroupName -Name $AzureRMVm.Name -Tag $AzureRmVm.Tags -ResourceType ‘Microsoft.Compute/VirtualMachines’


Start-AzureRmVM -Name $AzureRmVm.Name -ResourceGroupName $AzureRmVm.ResourceGroupName

#Run this post patching, when you are ready for the servers to be turned off again.

function Stop-AzurePatching {

foreach($AzureRmVm in (Get-AzureRmResourceGroup | Get-AzureRmVm))
if($AzureRmVm.Tags.Keys -like “*AutoShutdownSchedule*”)
$AzureRmVm.Tags.Remove(‘AutoShutdownSchedule’) | Out-Null
$AzureRmVm.Tags.Add(‘AutoShutdownSchedule’,’8PM -> 5AM, Saturday, Sunday, December 25′) | Out-Null

Set-AzureRmResource -Confirm:$FALSE -ResourceGroupName $AzureRmVm.ResourceGroupName -Name $AzureRMVm.Name -Tag $AzureRmVm.Tags -ResourceType ‘Microsoft.Compute/VirtualMachines’


There is more on Azure Fundamentals here.

Login to Azure Powershell

I find this to be a handy addition to any Azure script or just to run when i open Azure Powershell, it allows me to sign into Azure along with using the Out-Grid to pick a subscription and Resource Group.

# Sign-in with Azure account credentials


# Select Azure Subscription

$subscriptionId =
(Get-AzureRmSubscription |
Out-GridView `
-Title “Select an Azure Subscription …” `

Select-AzureRmSubscription `
-SubscriptionId $subscriptionId

# Select Azure Resource Group

$rgName =
(Get-AzureRmResourceGroup |
Out-GridView `
-Title “Select an Azure Resource Group …” `