Maksim Kabakou - Fotolia

Using Windows PowerShell scripts for task automation

Solutions providers will find that executing Windows PowerShell scripts for task automation will make jobs, such as creating virtual machines or consolidating old servers, easier.

Solutions provider takeaway: Windows PowerShell scripts can be used by solutions providers for task automation, which will allow them to let PowerShell take on time-consuming jobs such as consolidating old servers.

Automating common tasks using the Windows Scheduler

IT personnel today spend a lot of time on repetitive tasks to accomplish various jobs. PowerShell provides a powerful language that can be used to write and execute scripts. These scripts can eliminate repetitive tasks and add the necessary logic to complete complex jobs. Since VMM is built entirely on top of PowerShell, anything an administrator can do in the Administrator Console can also be accomplished via PowerShell cmdlets. If you combine that with the ability to integrate with .NET and other data stores that are PowerShell-ready, an administrator should be able to translate a lot of manual work into PowerShell scripts. The ability to schedule PowerShell scripts at specified intervals allows an administrator to do passive management of their system and let PowerShell do some of the heavy lifting during nonworking hours.

Once you have a PowerShell script ready, you may want to execute it at regular intervals and capture its results in a log file. If the cmdlets change data in VMM, you can also view the results in the Administrator Console's jobs view. There are a couple of ways to create a scheduled task in Windows Server. In this section, we will show you how to do this from the Task Scheduler user interface. Optionally, you can use the schtasks.exe utility to create a scheduled task.

To schedule a task from the Task Scheduler, follow these steps:

  1. Open the Task Scheduler MMCsnap-in. Task Scheduler is located in either Control Panel\System and Security\Administrative Tools\Task Scheduler or Control Panel\Administrative Tools\Task Scheduler, depending on the version of Windows installed.
  2. Select Create Task.
  3. Enter a Task Name like Windows PowerShell automated script.
  4. Select Run Whether User Is Logged On Or Not and chose to store the password.
  5. Select Change User Or Group to enter a user that has the proper VMM privileges to execute this PowerShell script.
  6. In the Triggers tab, enter the schedule you would like to create for this scheduled task. For example, you can choose to run this script daily at 8 p.m.
  7. In the Actions tab, as shown in Figure 8.13, add a new action and select Start A Program. In the program path, enter D:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.
  8. This is the full path to Windows PowerShell 1.0.
    For arguments, enter the following:

-PSConsoleFile "D:\Program Files\Microsoft System Center Virtual Machine Manager 2008 R2\bin\cli.psc1" -Command " & '\\\ MSSCVMMLibrary\Scripts\GetVMStatus.ps1'"
-NoProfile -Noninteractive

If you were to execute this command from a regular command window, it would look like this:

D:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -PSConsoleFile "D:\Program Files\Microsoft System Center Virtual Machine Manager 2008 R2\bin\cli.psc1" -Command " & '\\\MSSCVMMLibrary\Scripts\GetVMStatus.ps1'" -NoProfile -Noninteractive

  1. Click OK and enter the password for the account that will execute the scheduled task.
  2. From the Task Scheduler MMC, you can view all your scheduled tasks, check for their last run time, and see if there were any errors in execution based on the last run result.

Figure 8.13 

Adding the scheduled task action
Adding the scheduled task action

Sometimes, it is easier to check if a scheduled task is executing by looking at a log file. The following sample PowerShell script shows you how to log that information to a file:

Write-Output "Script executing at " (date)

# Get a connection to the local VMM server
$c = get-vmmserver localhost

# Make a sample query to get some data from VMM
$results = get-vm | select name, status, vmid, ID, hostname

# Create a log file in the temp directory
$filepath = "$env:temp\PSscriptOutput.log"

# Append to the log file the current time and the data retrieved from VMM
Add-Content (date) -Path $filepath
Add-Content $results -Path $filepath
Add-Content "-------------" -Path $filepath

Because scheduled PowerShell scripts don't offer the same degree of debugging, you need to ensure that the proper execution policies are in place for PowerShell scripts. It is recommended that all scripts you execute using the Task Scheduler are signed using a code signing certificate issued by a certificate authority. This will enable you to set the PowerShell execution policy to a more secure level like the AllSigned option. After you sign a script using the Set-AuthenticodeSignature cmdlet, you will need to add the publisher of the script to your trusted publishers. PowerShell will prompt you to do that on the first execution of the script.

About the book

This chapter excerpt on Automation Using PowerShell is taken from the book Mastering Virtual Machine Manager 2008 R2. This book offers information on the features, capabilities and architecture that solutions providers need for a successful Virtual Machine Manager (VMM) 2008 R2 deployment. You will find out the best ways to accomplish tasks such as deploying virtual machines to Hyper-V hosts or backing up and planning for recovery of the VMM server.

 In Chapter 9, ''Writing a PRO Pack,'' we will cover the PRO feature of VMM. PRO allows an administrator to execute a PowerShell script or perform a VMM action based on a set of alerts detected by System Center Operations Manager (OpsMgr). OpsMgr is a comprehensive data center monitoring tool. In this case, a PowerShell script is executed in response to a dynamic event.

Windows PowerShell examples

In the following sections, we will list a few different Windows PowerShell scripts that use the VMM cmdlets to accomplish important tasks in VMM, make it easier for an administrator to execute repetitive actions, and allow an administrator to get quick status on the health of VMM objects.

Creating virtual machines

There are many ways to create a virtual machine in VMM. In this section, we will take a look at an example of how to create a highly available (HA) VM and find the best suitable host on which to place it. The best suitable host is found by the Intelligent Placement feature of VMM based on the properties of the VM and the available hosts. Listing 8.2 contains the code for creating the HA virtual machine.

Listing 8.2: Creating a new highly available virtual machine

# Get a connection to the VMM server
$c = Get-VMMServer 'localhost'

# Create the Job Group ID. This is the Guid that pairs all the cmdlets
# necessary to ensure that the new Virtual Machine creation is
# Successful. Every cmdlet that specifies the same Job Group ID will
# be part of a set and will be executed in order after the final command
# that includes the same Job Group ID runs. In this case, the final
# command is the New-VM cmdlet.
$JobGroupID = [System.Guid]::NewGuid().ToString()

# Enter the VM Name
$VMName = "virtualmachine1"

#Create a virtual NIC
New-VirtualNetworkAdapter -JobGroup $JobGroupID -PhysicalAddressType
Dynamic -VLANEnabled $false

# Create a virtual DVD
New-VirtualDVDDrive -JobGroup $JobGroupID -Bus 1 -LUN 0

# Check if another HW profile has the same name and delete it if there is
$HardwareProfile = Get-HardwareProfile | where {$_.Name -eq "HWProfile"}
if ($HardwareProfile -ne $null)


Write-Warning "Deleting the existing hardware profile with the same name"

Remove-HardwareProfile $HardwareProfile

# Create a new hardware profile with the user preferences
# The -HighlyAvailable property of this cmdlet is the one indicating
# that this Virtual Machine should be a Highly Available one
$HardwareProfile = New-HardwareProfile -Owner "vmmdomain\administrator"
-Name "HWProfile" -CPUCount 1 -MemoryMB 2048 -HighlyAvailable $true
-NumLock $false -BootOrder "CD", "IdeHardDrive", "PxeBoot", 
"Floppy" -LimitCPUFunctionality $false -JobGroup $VMGuid

# Create a new VHD for the VM
$DiskDrive = New-VirtualDiskDrive -IDE -Bus 0 -LUN 0 -JobGroup
$JobGroupID -Size 10240 -Dynamic -Filename "virtualmachine1.vhd"

# Get all the hosts and their ratings for this VM's HW profile
$AllHosts = Get-VMHost
$hostrating = Get-VMHostRating -VMHost $AllHosts
-HardwareProfile $HardwareProfile -DiskSpaceGB 10 -VMName $VMName

# Order the host ratings and check if we have at least one
# positive star rating for this VM
$orderedrating = $hostrating | sort-object rating -descending
Write-Output $orderedrating

# If the rating is 0, exit and don't call new-vm
if ($orderedrating -is [Array])

# we have multiple results, so pick the top one

$targethost = $orderedrating[0].VMhost

if ($orderedrating[0].Rating -eq 0)


Write-Warning "There is no suitable host for this VM's profile"
Write-Warning $orderedrating[0].ZeroRatingReasonList[0]



$targethost = $orderedrating.VMhost
if ($orderedrating.Rating -eq 0)


Write-Warning "There is no suitable host for this VM's profile"
Write-Warning $orderedrating.ZeroRatingReasonList[0]



Write-Output "We will be creating a new VM on host $targethost"

# Get the operating system from a list of predefined OS Names in VMM
$OperatingSystem = Get-OperatingSystem | where {$_.Name -eq
"64-bit edition of Windows Server 2008 Enterprise"}

# Find the path for the LUN/Disk to host the files for the new HA VM
# Make sure this volume is not in use, is a cluster volume
# (with cluster resources already created), and is available
# for placement

$targetpath = get-vmhostvolume -VMHost $targethost
| where-object -filterscript {$_.IsClustered -eq $true}
| where-object -filterscript {$_.InUse -eq $false}
| where-object -filterscript {$_.IsAvailableForPlacement
-eq $true}
if ($targetpath -eq $null)

Write-Warning "There is no suitable cluster disk to place this VM on"


if ($targetpath -is [Array])

# Pick the first available disk to place this VM on
$targetpath = $targetpath[0].Name


$targetpath = $targetpath.Name


# Create the new-vm in an asynchronous way
New-VM -VMMServer $c -Name $VMName -Description
"new HA VM to learn more about PowerShell"
-Owner "vmmdomain\administrator" -VMHost
$targethost -Path $targetpath -HardwareProfile $HardwareProfile
-JobGroup $JobGroupID -RunAsynchronously -OperatingSystem
$OperatingSystem -RunAsSystem -StartAction NeverAutoTurnOnVM
-StopAction SaveVM

For more information on this topic, check out our features on SCVMM PowerShell commands, PowerShell JEA and PowerShell malware.

Dig Deeper on MSP technology services

Cloud Computing
Data Management
Business Analytics