On Windows PowerShell and other admin-related topics

Test-Connection error handling gotcha in PowerShell 2.0

The Test-Connection cmdlet in Windows PowerShell was introduced in version 2.0, with the purpose of sending ICMP echo request packets ("pings") to one or more computers as stated in the cmdlet`s documentation.

The cmdlet has a number of useful parameters, for example –Count to specify the number of request packets to send (the default is 4) and –Quiet to suppress errors and make the cmdlet return either true or false:


The –Quiet parameter is very useful when writing a script or function where you only want to perform an operation if the target computer responds to ping requests. A basic example of using this technique:

if (Test-Connection -ComputerName doesntexist -Count 1) {            
#Proceed with script operation            

A few weeks ago I stumbled upon a problem when trying to use a try/catch block in a PowerShell function. What I wanted to do was to catch a ping exception when using Test-Connection. Here is the code I was running:

Test-Connection -ComputerName doesntexist -Count 1 -ErrorAction stop            
catch [System.Net.NetworkInformation.PingException]            
'Catched PingException'            
'General catch'            

To my surprise, the PingException wasn`t catched:


I then tried setting up a new System.Net.NetworkInformation.Ping object, to see if the PingException catch worked when using the object`s Send-method:


This worked, so the problem seemed to be related to the Test-Connection cmdlet.

Earlier this week I attended the PowerShell Deep Dive conference in Frankfurt, which was part of The Experts Conference 2011. In the evening the organizers set up a Script Club, where the attendees could explore various PowerShell features together, as well as getting assistance in problem solving. Together with PowerShell MVP Jeff Hicks I sat down and looked into the issue with Test-Connection. As we couldn`t figure out why the PingException catch block didn`t work as expected, we got assistance from a PowerShell team member who was attending the conference, Jason Shirk.

Jason explained to us that there is a bug with Test-Connection`s ErrorAction parameter in PowerShell 2.0, which is resolved in PowerShell 3.0 (not in CTP 1). This means my example above will work in the next version of PowerShell. Until then, Jason showed us a workaround for PowerShell 2.0:

Test-Connection -ComputerName doesntexist -Count 1 -ErrorAction stop            
catch [System.Management.Automation.ActionPreferenceStopException]            
try {            
throw $_.exception            
catch [System.Net.NetworkInformation.PingException] {            
'Catched PingException'            
catch {            
'General catch'            

The workaround is to go into the inner exception of ActionPreferenceStopException to perform the PingException catch.

Many thanks to Jason Shirk for the assistance. For others, I would highly recommend to attend the next PowerShell Deep Dive. In addition to great presentations, you also get to network with other PowerShell enthusiasts, as well as attending the very fun and exciting Script Club in the evenings.


Related resources

October 23, 2011 Posted by | Windows PowerShell | , , , | 1 Comment

What`s New in Windows PowerShell 3.0

Since the release of Windows 7 and Windows Server 2008 R2, Windows PowerShell is included in the operating system and enabled by default. This means Windows PowerShell 3.0 will be available in the next version of Windows.

A preview version for developers of the next Windows version was released a few weeks ago, which means we also got a preview of Windows PowerShell 3.0. The  preview version of the client operating system is available here, while the server version is available on MSDN.

Earlier this week the PowerShell team announced that a Community Technology Preview (CTP 1) is available for download, which means we can also try out PowerShell 3.0 on computers running Windows 7 and Windows Server 2008 R2. The current version of the Windows Management Framework includes Windows PowerShell 2.0, Windows Remote Management (WinRM) 2.0 and Background Intelligent Transfer Service (BITS) 4.0, while the new Windows Management Framework CTP contains Windows PowerShell 3.0, Windows Management Instrumentation (WMI) and Windows Remote Management.

Some of the most important new features in PowerShell 3.0 is listed in the previous mentioned announcement from the PowerShell team, but there is also a huge number of other new features.

A great number of persons in the PowerShell community has already started to discover and write about the new features. One of them is the new Windows PowerShell Web Access in the next version of Windows Server, which I`ve previously written an article about.

Instead of listing all the articles I`ve discovered so far in this article, I posted them as a TechNet Wiki article as part of the existing PowerShell V3 Guide:

TechNet Wiki: PowerShell V3 Guide
TechNet Wiki: PowerShell V3 Featured articles

I would like to encourage you to contribute to the TechNet Wiki article when you discover new writings about Windows PowerShell 3.0.

September 25, 2011 Posted by | Windows 8, Windows PowerShell | | Leave a comment

Windows PowerShell Web Access

In the Windows Server Developer Preview (“Windows 8 Server”) released recently, a preview version of Windows PowerShell 3.0 is also included. In addition to the many news in the next version of PowerShell which I won`t cover in this article is a brand new feature named Windows PowerShell Web Access. As the name indicates this makes it possible to use Windows PowerShell using a browser from a computer, in addition to mobile devices.

Installation, configuration and user experience

Windows PowerShell Web Access is available as a feature in the new Server Manager:


After the feature is installed, some additional steps which is described in %systemroot%\Web\PowerShellWebAccess\wwwroot\README.txt is required:

To complete the installation of Windows PowerShell Web Access, please perform the
following tasks:

1) Open a Windows PowerShell console with elevated user rights.

To do this, right click on PowerShell.exe, or a Windows PowerShell shortcut,
and then click “Run as administrator.”

2) Be sure your Windows PowerShell environment is configured to run scripts.

For more information, see “Running Scripts from Within Windows PowerShell”

3) Run the following script:


This is typically C:\Windows\Web\PowerShellWebAccess\wwwroot\setup.ps1

4) Create a server certificate.

For a test server, you can create a self-signed certificate by using the
Web Server (IIS) management console:


From within the IIS management console, open the Web Servers parent node.
This is typically the node immediately under the Start Page node.

In the results pane, select “Server Certificates” on the center pane, then
select “Create Self-Signed Certificate.”

5) Create an SSL binding.

In the IIS management console, select “Default Web Site,” and then click
“Bindings” on the “Actions” menu. Click “Add,” select “https” on
the “Type” pull-down menu, and then in the “SSL certificate” list, select the
certificate that you created in step 4.

For more information about how to create a server certificate and an SSL binding,
see “How to Set Up SSL on IIS 7”

The setup.ps1 script will create a new Web Application Pool and a new Web Application in Internet Information Services:

$ErrorActionPreference = ‘stop’

$wwwroot = “${env:\windir}\Web\PowerShellWebAccess\wwwroot”

if (!(Test-Path $wwwroot))
Write-Error “PowerShell Web Access has not been installed on this machine”

# Copy localized files to neutral location
foreach ($target in ($wwwroot,”$wwwroot\bin”))
foreach ($culture in (“en”,”en-us”,”qps-ploc”))
$source = “$target\$culture”

        if (Test-Path $source)
copy “$source\*” $target

# Setup ASP.NET application
Import-Module WebAdministration

if (Get-WebApplication -name “pswa”)
Write-Error “The Windows PowerShell Web Access application (pswa) already exists on this machine”

New-WebAppPool “pswa”

New-WebApplication -Name “pswa” -Site “Default Web Site” -PhysicalPath $wwwroot -ApplicationPool “pswa”

If the script runs successfully, it returns the following output:

PS C:\> C:\Windows\Web\PowerShellWebAccess\wwwroot\setup.ps1

Name                     State        Applications

—-                     —–        ————

pswa                     Started

Path             : /pswa

ApplicationPool  : pswa

EnabledProtocols : http

PhysicalPath     : C:\Windows\Web\PowerShellWebAccess\wwwroot

The final configuration step is to create and add a binding to a certificate as described in the link provided in the readme.txt file.

When done, you can access the feature by using the URL https://<servername>/pswa :


Specify credentials and a computer name to connect to, then hit the “Sign in” button. Another connection type available is “Connection URI”:


The options available under “Advanced Options”:


The available authentication types:


After signing in, you`ll be presented with a console looking like this:


The console host is called “ServerRemoteHost”:


Tab-completion works just like in the regular Windows PowerShell console host, and we also have access to the history by pressing the up and down arrows. To logoff, there is a Logoff-button in the bottom right corner.

The PowerShell Web Access also works perfectly fine on mobile devices. I`ve tried it on a Windows Phone 7 device, but unfortunately I don`t have any screen captures to share yet.

Congratulations to the Windows PowerShell team for providing this excellent new feature!

Note: Please be aware that this is a feature in a prerelease version of the next version of Windows Server, and thus the feature might be different in the final product.

Update 15.09.2011

Screen capture from PowerShell Web Access running on an Iphone:









Update 21.03.2012:
With the release of Windows Server 8 beta the configuration steps has changed. After installing the PowerShell Web Access feature you need to install a PSWA Web Application:


By default no authorization rules exist. Here is an example on how to create one that allows access to all computers (*) for the specified username/group:

Add-PswaAuthorizationRule -UserName domain\username -ComputerName * -ConfigurationName microsoft.powershell

Detailed instructions is available in the Deploy Windows PowerShell Web Access article on Microsoft TechNet.

September 14, 2011 Posted by | Windows PowerShell | , , | 26 Comments

Hyper-V: How to unbind a physical NIC from a Virtual Switch using WMI and PowerShell

If you`re not already familiar with networking in Microsoft Hyper-V I would recommend you to have a look at this whitepaper from Microsoft, which described how networking works in Hyper-V.

The following solution will describe a problem which might occur when configuring virtual networks in Hyper-V. Consider the following scenario:

  • You`re about to configure a new external virtual network in Hyper-V using Hyper-V Manager remotely from another computer. This is a common scenario when working with the Core edition of Windows Server 2008/2008 R2.
  • When selecting the physical NIC to bind to the new virtual network, you choose the adapter which you are remotely connecting to the Hyper-V host through.

What happens in this scenario is that the Virtual Switch Management Service is binding the external Ethernet port for the selected NIC to the Microsoft Windows Virtualization network subsystem. What normally should happen next is that the converted Ethernet port should be bound to the new virtual switch you are creating. However, this never happens since the NIC you are remotely managing the Hyper-V host through is no longer available in the parent operating system. This leaves the NIC in an “orphaned” state, since you cannot use the NIC in the parent operating system, and it`s not in use by any virtual networks.

To resolve this issue, whether using the full GUI version or the Core version of Windows Server, you need to manually unbind the the Ethernet port. There is an UnbindExternalEthernetPort available on the Msvm_VirtualSwitchManagementService WMI class, which is fully documented in this article on MSDN.

To invoke the WMI method we can use Windows PowerShell. To ease the procedure I`ve created a PowerShell function you can use if you ever come into the need for manually unbinding an external Ethernet port in Hyper-V:


Function Select-List
    Param   ([Parameter(Mandatory=$true  ,valueFromPipeline=$true )]$InputObject, 

    begin   { $i= @()  }
    process { $i += $inputobject  }
    end     { if ($i.count -eq 1) {$i[0]} elseif ($i.count -gt 1) {
                  $Property=@(@{Label=“ID”; Expression={ ($global:Counter++) }}) + $Property
                  format-table -inputObject $i -autosize -property $Property | out-host
                 $Response = Read-Host “Select NIC to unbind”
                  if ($response -gt “”) { 

function Remove-HVExternalEthernetPort {

$ExternalEthernetPort = Get-WMIObject -class “Msvm_ExternalEthernetPort” -namespace “root\virtualization” | Select-List -Property name

$HVSwitchObj = Get-WMIObject -class “MSVM_VirtualSwitchManagementService” -namespace “root\virtualization”

if ($ExternalEthernetPort) {
else {
throw “An error occured. Choose a valid ExternalEthernetPort from the provided list”


Note: The Select-List function is a modified version of the Select-List function available in the PowerShell Management Library for Hyper-V available on CodePlex (see link below).

You can either paste the function into a PowerShell session or save it into ps1-file and dot source it. When done you can invoke the function like this:


When you`ve entered the index number for the NIC you want to remove, a return value of 0 indicates the operation succeeded. Any other value indicates an error (look at the previous mentioned MSDN-article for more information).


More resources on managing Hyper-V using PowerShell

PowerShell Management Library for Hyper-V – this is an excellent PowerShell module for managing Hyper-V available on CodePlex

System Center Virtual Machine Manager 2012: Scripting

System Center Virtual Machine Manager 2008 R2: Scripting

Hyper-V WMI Using PowerShell Scripts

Script: Determining Virtual Switch Type Under Hyper-V

August 30, 2011 Posted by | Hyper-V, Hyper-V R2, Scripting, Virtualization, Windows PowerShell | , , | 1 Comment

How to automatically convert Windows PowerShell transcripts into script-files

In Windows PowerShell we can use the Start-Transcript cmdlet to record PowerShell sessions to a text-file. This will record both the commands you`ve run as well as the output from the commands.

Windows PowerShell MVP Jeffery Hicks recently wrote a great tip in his Friday Fun series on his blog, which tells you how to convert a PowerShell transcript into a PowerShell script file. That is, you`ll get a ps1-file which contains the commands extracted from the transcript. Combined with an object event which triggers when PowerShell exits, this can be set up to happen automatically. Jeff actually blogged another Friday Fun tip a couple years ago which describes how to set up such an object event.

Lets have a look at an example on how this would work. First we launch a new PowerShell session and executes a few commands:



When we exit PowerShell we`ll get two files in a specified log directory:



The transcript file (txt-file) contains all commands, errors and output from our session:



The PowerShell script file (ps1-file) contains a script header and the commands from our session:



This means that every PowerShell session automatically generates a PowerShell script file which can be the foundation for a new script.

To set this up you first need to copy the Export-Transcript PowerShell function from Jeff`s blog-post and add it to your PowerShell profile (Microsoft.PowerShell_profile.ps1), in addition to the following:


#Define variable for the transcript path, which we`ll use to generate the path to the ps1-file
$transcriptlog = ("C:\PS-logs\PS-Transcript_"+"{0:yyyy-MM-dd_HH-mm-ss}" -f (Get-Date)+".txt")
Start-Transcript -Path $transcriptlog | Out-Null

#Export transcript to ps1-file on exit
Register-EngineEvent PowerShell.Exiting –action {
 -Transcript $transcriptlog -Script (($transcriptlog.Replace("Transcript","Script")).Replace("txt","ps1"
| Out-Null


While this is very useful, there is a few gotcha`s to be aware of:

  • This doesn`t work if your exiting PowerShell using the X button. The PowerShell.Exiting event is only triggered when using the exit command.
  • This doesn`t work in the Windows PowerShell ISE, since that PowerShell host doesn`t support transcripts.
  • If you`ve customized your PowerShell prompt, you`ll need to tweak the Export-Transcript function to match the last letter in your prompt.

August 12, 2011 Posted by | Windows PowerShell | , | Leave a comment

Getting starting with Cisco UCS PowerShell Toolkit

Cisco – widely known as a networking infrastructure vendor – entered the blade server market in 2009. Their offering is called Unified Computing System, described by Gartner as a fabric-enabled, enterprise-class platform with good integration of networking, virtualization, management tools and storage. On the 2011 Gartner Magic Quadrant for Blade Servers they`re defined as a visionary vendor, and it will be interesting to see if they can challenge the 3 leaders Dell, IBM and HP.

The Cisco Unified Computing System is quite different from traditional blade systems, in that the server profiles (so called service profiles) is independent from the physical blade servers. An example to describe what this means is that a physical blade server might fail and be replaced, while the server profile keeps unique ID`s like MAC addresses, World Wide Names (WWN`s) and so on. If using boot from SAN rather than local disk drives, physical interaction is not required to get the system back online if a spare blade server is available.


The UCS core components

  • Blade Chassis – Blade server enclosure
  • Cisco UCS Manager – Embedded into the Fabric Interconnect. Provides management capabilities
  • Cisco UCS fabric interconnect – Provides networking (Ethernet/Fibre Channel) and management for connected blades and chassis`
  • Fabric Extenders – Provides connection between the interconnect fabric and the blade enclosures

A photo showing the Cisco Unified Computing System architecture is available here ( In regards of management, all aspects of Cisco UCS can be managed through an XML API. This makes it possible for 3rd parties to offer management solutions, and integration with other products. An example of a 3rd party product is the Cisco UCS Iphone/Ipad application for managing and monitoring the system. Links for more information on the management model and the XML API is available in the resources section in the bottom of this article.


Cisco UCS PowerShell Toolkit

Based on a customer request from an early adaptor, Cisco provided PowerShell support for managing their UCS product through the XMP API. With the Microsoft automation strategy in mind, this was an excellent choice. It will make integration into products like System Center Orchestrator (formerly Opalis) very easy, and the also make the product attractive for enterprises. The PowerShell administration tool is available as a module part of the Cisco UCS PowerShell Toolkit.

A great way to learn using the Cisco UCS PowerShell Toolkit is downloading the Cisco UCS Emulator. This is a virtual machine image which can be imported into VMware Player or VirtualBox. When the VM is up and running you can access both the UCS Manager (http URL is shown when the VM has started) and the XML API. A great feature is that you can import the configuration from a production UCS to simulate administration changes in a lab environment.

Next, you can download the latest versions of both the Cisco UCS PowerShell Toolkit (aka UCSMPowerTool) and the PowerShell Toolkit User Guide from this website.

The installer will by default put the files in %programfiles%\Cisco\UCSMPowerToolkit:


CiscoUCSPS.dll is the assembly which can be imported as a module in Windows PowerShell 2.0 and later. You can either double-click LaunchUCSPS.bat or invoke StartUCSPS.ps1 from an existing PowerShell session to get started. Alternatively you can use Import-Module from an existing PowerShell session like this:
Import-Module “C:\Program Files (x86)\Cisco\UCSMPowerToolkit\CiscoUCSPS.dll”

I would suggest rather than installing to the Program Files folder (which requires administrative privileges), that Cisco generates a module manifest and install the module to the default PowerShell module directory (C:\Users\<username>\Documents\WindowsPowerShell\Modules).

When the module is imported we can use Get-Command with the –Module parameter to list all command inside the CiscoUCSPS module:


The current version of the module contains 149 cmdlets, so all commands are not shown in the above screenshot.

The first thing we need to do is connect to an instance of the UCS Manager. If using the Cisco UCS Emulator you can view the management  IP address when the virtual machine has started:


We then use the Connect-UCSM cmdlet to connect to the UCS Manager:


The default credentials for the UCS Emulator is config/config.

Next we can start exploring cmdlets like Get-Blade and Get-Vlan. Note that by default the cmdlets outputs a lot of information for each object, so I`ve picked out a few properties to show using Format-Table:


Going further it`s easy to automate things like adding VLAN and assigning it to a vNIC template:



Although the PowerShell coverage isn`t 100% yet, it`s possible to administer all aspect of the UCS directly through the XML API from PowerShell using the Invoke-XmlCommand cmdlet.



Cisco Unified Computing

A Platform Built for Server Virtualization: Cisco Unified Computing System

Cisco Unified Computing Forums

Automating Cisco UCS Management with Windows PowerShell

PowerScripting Podcast – Josh Heller from Cisco on UCS and PowerShell

Cisco UCS Manager XML API Programmer’s Guide

Cisco UCS Manager API Management Information Model

Cisco Developer Network: Unified Computing

Managing your Cisco UCS from an iPhone or iPad

July 23, 2011 Posted by | Scripting, Virtualization, Windows PowerShell | , , | 2 Comments

Adding printer drivers from a print server using Windows PowerShell

Managing printer drivers in a Remote Desktop Services (formerly Terminal Services) environment can be a challenge for administrators. There are many ways to ease this challenge, including third party solutions such as ThinPrint and UniPrint. When “thick” drivers are used on the RDS servers, all printer drivers must be installed locally on every server. Citrix XenApp has a printer driver replication feature which makes it possible to distribute printer drivers from a source server to one or more destination servers in a farm.

There might be situations where none of the mentioned solutions can be used for various reason, i.e. financial costs. A common way to solve this problem is to map all printer connections from a specified print server using administrative credentials during the initial setup of each RDS server. This solves the problem, but it can be time consuming as all printers that uses the same driver is being installed. Even though the driver is already installed on the local computer, it takes some time to process each printer connection.

I recently faced this challenge, as the installation of all printer connections from a few specified print servers took 30-40 minutes using a legacy script. I then wrote an advanced function in PowerShell to make the procedure more effective. This was accomplished by installing a printer connection only for unique printer drivers.
An example: A print server has 500 shared printer objects, while there is only 10 unique printer drivers. It would make more sense to add a printer connection (in order to install the driver) to 10 printer objects rather than 500, given the time consumed by installing a printer connection.

The function is available for download from here.

Sample usage and output:




There is a switch option added to the function called Clean. If this parameter is specified the function will also remove all mapped printer connections for the current user.

The function doesn’t`t provide any log options. However, it produces PowerShell objects, so it would be easy to pipe the output to a file.
An example on how to export the output objects to a csv-file:


But what about printer drivers added to the print servers after the function is run on an RDS server? One way to solve this could be adding the PowerShell function to a script-file which is set up as a scheduled task to run i.e. once a day on every RDS server.  If the scheduled task is set up using Group Policy Preferences, it will be automatically created on every new RDS server that is added later on. Beside scheduling the task to run at specified intervals, the print server administrator may also invoke the scheduled task remotely on every RDS server whenever a new print driver is added to a print server. The details on how to do this is previously described in this blog-post.

Since the function might be run several times on the same computer, it also checks if the driver to be installed is already in place on the local computer. This means that after the first run, only printer drivers added to the print server after the first run is actually installed. This makes the script more effective, and depending on the number of shared printer objects on the specified print server, it shouldn’t`t run for many seconds.

Coming back to the before mentioned example (~600 printer objects, ~50 unique drivers) where it took 30-40 minutes to install printer drivers from a print server, when using the Add-PrinterDriver PowerShell function the execution ran for 4 minutes. After the first run, subsequent executions ran for  20 seconds.

July 3, 2011 Posted by | Print management, Remote Desktop Services, Scripting, Terminal Services, Windows PowerShell, Windows Server 2008, Windows Server 2008 R2 | , , , , | 5 Comments

Use Windows PowerShell to get antivirus product information

Windows Security Center has been available in Windows client operating systems since Windows XP SP2. This is a useful feature for monitoring the overall for security status for the system, including antivirus, antimalware and firewall protection. In situations no monitoring software like System Center Operations Manager is in place to monitor the security health on client computers, one option is to use Windows Management Instrumentation. There is a WMI namespace called root\SecurityCenter2 which exposes information from the Windows Security Center, like what antivirus product is installed on the system.

I`ve created PowerShell function to query computers for information on what antivirus is installed as well as the current status for antivirus definitions and real-time protection:

function Get-AntiVirusProduct {
param (
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)

$AntiVirusProduct = Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct  -ComputerName $computername

#Switch to determine the status of antivirus definitions and real-time protection.
#The values in this switch-statement are retrieved from the following website:

switch ($AntiVirusProduct.productState) {
"262144" {$defstatus = "Up to date" ;$rtstatus = "Disabled"
"262160" {$defstatus = "Out of date" ;$rtstatus = "Disabled"
"266240" {$defstatus = "Up to date" ;$rtstatus = "Enabled"
"266256" {$defstatus = "Out of date" ;$rtstatus = "Enabled"
"393216" {$defstatus = "Up to date" ;$rtstatus = "Disabled"
"393232" {$defstatus = "Out of date" ;$rtstatus = "Disabled"
"393488" {$defstatus = "Out of date" ;$rtstatus = "Disabled"
"397312" {$defstatus = "Up to date" ;$rtstatus = "Enabled"
"397328" {$defstatus = "Out of date" ;$rtstatus = "Enabled"
"397584" {$defstatus = "Out of date" ;$rtstatus = "Enabled"}
default {$defstatus = "Unknown" ;$rtstatus = "Unknown"

#Create hash-table for each computer
$ht = @{}
$ht.Computername = 
.Name = $AntiVirusProduct.displayName
$ht.ProductExecutable = $AntiVirusProduct.pathToSignedProductExe
$ht.‘Definition Status’ = 
.‘Real-time Protection Status’ = $rtstatus

#Create a new object for each computer
New-Object -TypeName PSObject -Property $ht



Sample output:


The root\SecurityCenter2 namespace isn`t documented on MSDN, so it`s hard to find information on the properties and methods we find in the different classes in the namespace.

The productstate property of the AntiVirusProduct class is exposed as a integer value, which needs to be converted to a hexadecimal value. Then the different bytes in the value contains information in regards to definition updates and real-time protection. More information on this is available here. I haven`t found a complete reference to all possible values, the best I could find is available here.

The above function outputs Windows PowerShell objects, so it`s possible to filter the output i.e. based on the “Definition Status” property.  The computername parameter also supports value from pipeline to make it easy to get the computers to query from i.e. Active Directory without using a foreach construct. A few examples:

#Get antivirus product information for all computers in the specified OU/container
Import-Module ActiveDirectory
Get-ADComputer -SearchBase "CN=Computers,DC=contoso,DC=local" -Filter * | Select-Object -ExpandProperty name | Get-AntiVirusProduct

#Filter using Where-Object to get all computers where the Definition State is not "Up to date"
Get-AntiVirusProduct -computer (Get-Content computers.txt) | Where-Object {$_.‘Definition Status’ -notlike ‘Up to date’}


The root\SecurityCenter2 namespace is available on Windows Vista SP1 and above. Windows Security Center is not available on server operatingsystems, meaning that the root\SecurityCenter2 namespace also isn`t available. In Windows XP SP2 the namespace is called root\SecurityCenter, but the properties are not the same as in root\SecurityCenter2. It`s possible to get the function work on Windows XP, but you would need to customize it to match the properties available in the root\SecurityCenter namespace.

I would encourage you to add error handling before using this function in a production environment, i.e. adding a test to check if the remote computer is available and allowing RPC-communication. If you would like to explore the other classes in the root\SecurityCenter2 namespace for working with firewall and antispyware products, you can start by exploring the available classes like this: Get-WmiObject -Namespace root\SecurityCenter2 -List

June 12, 2011 Posted by | Desktop management, Scripting, Windows 7, Windows PowerShell, Windows Vista | , | Leave a comment

Enable Persistent Mode for Cluster Resource Groups using the PowerShell Failover Clustering module

In Failover Clustering in Windows Server 2008 R2, Persistent Mode is intended to allow resource groups to come online on the node which an admin last moved them to. This setting is enabled by default when a virtual machine is created with Failover Cluster Manager. If you create virtual machine via System Center Virtual Manager this setting is not enabled.

By default, cluster roles have this setting disabled, except for Hyper-V virtual machine cluster roles, which have this enabled by default. This setting is useful when the cluster is shutdown and later started, in order to better distribute the resources across the nodes and allow them to come online faster, as they were likely spread across the nodes before the cluster was offlined. Otherwise, all the resources will attempt to restart on the first nodes which achieve quorum and compete for resources. This only applies to a group if it did not failover after being placed by the administrator. If a group has failed over since the last administrator placement, it is brought online on the node which the administrator last move it to.

Reference and more info regarding the Auto Start, Persistent Mode and Group Wait Delay features is available on the Clustering and High-Availability blog.

Auto Start can be enabled/disabled in bulk by marking all Cluster Resource Groups in Failover Cluster Manager and selecting “Enable auto start”/”Disable auto start”.

For Persistent Mode the only available option in Failover Cluster Manager is to right click each Cluster Resource Group and selecting/de-selecting the checkbox for “Enable persistent mode”:


To change this setting for all Cluster Resource Groups in an automated fashion you can use the Failover Cluster module for PowerShell, which I wrote an introduction to here.

Here is an example on how you can do this:

Import-Module FailoverClusters
$clustergroups = Get-ClusterGroup -Cluster cluster01.domain.local
foreach ($clustergroup in $clustergroups) {
#To enable persistent mode: x To disable persistent mode: 4294967295

Although you can change the Auto Start setting in bulk in Failover Cluster Manager you might also want to do this in an automated fashion:

Import-Module FailoverClusters
$clustergroups = Get-ClusterGroup -Cluster cluster01.domain.local
foreach ($clustergroup in $clustergroups) {
#To enable Auto Start: 1 To disable Auto Start: 0

You can also change the Group Wait Delay cluster-wide property from the PowerShell Failover Clustering module, how to do this is explained in the above referenced blog-post from the Clustering and High-Availability blog.

For the next version of System Center Virtual Machine Manager I would expect that Persistent Mode is enabled by default, since Microsoft do recommend customers to enable this setting.

Update 08.12.2011: The value of the DefaultOwner property for configuring Persistent Mode is the number of the node you want to be the default owner. In example a value of 1 means the first node in the cluster.

June 3, 2011 Posted by | Failover Clustering, Hyper-V, Hyper-V R2, Scripting, Windows PowerShell, Windows Server 2008 R2 | , | 3 Comments

Administering Microsoft Office 365 using Windows PowerShell

Microsoft Office 365 is a software plus services offering from Microsoft, the successor to the existing offering Business Productivity Online Suite. The following services are included in the initial release of Office 365:

  • Exchange Online
  • Lync Online
  • Sharepoint Online
  • Office Professional Plus 2010

One major advantage in Office 365 compared to the previous version is the ability to offer single sign-on, also referred to as identity federation, which makes  the offering more attractive for enterprises. Another feature that makes it attractive for larger environments is the greatly enhanced support for administration using Windows PowerShell. Many of the PowerShell capabilities are built on the remoting capabilities in PowerShell version 2, while some requires installation of a PowerShell snapin or module.

Office 365 PowerShell Management Interface

The Office 365 PowerShell Management Interface offers the ability to administer service-wide features, and is not limited to a specific service like i.e. Exchange Online. The initial features that can be administered using this interface include the following:

  • Account SKUs
  • Company info
  • Contacts
  • Domains
  • Domain Federation
  • Groups
  • Partner Contracts
  • Role-based Access Control
  • Subscriptions
  • Users

This interface is available through a PowerShell Module available from here:

The Microsoft Online Services Sign-In Assistant 7.0 is a prerequisite for installing the Microsoft Online Services Module for Windows PowerShell, and is available from here:

When installed you can launch Windows PowerShell and perform the following steps:

Import-Module msonline
$cred = Get-Credential
Connect-MsolService -cred $cred
Get-Command –Module msonline

1) Import the module.

2) Create a credential-object stored in the variable $cred

3) Create a new remote PowerShell connection against the PowerShell endpoint for Office 365

4) List the cmdlets available


A shortcut to the module is also available on the Start-menu (you can skip step 1 if launching this shortcut):


Here is an overview of the available cmdlets:


You can find a complete reference for the cmdlets here.

Exchange Online

Exchange Online is based on Exchange Server 2010, and thus offers great capabilities for administration through PowerShell remoting. The Role-based Access Control introduced in Exchange Server 2010 also makes it possible to define custom RBAC roles to delegate administration.

To connect to the Exchange Online endpoint for PowerShell remoting we can use the following procedure:

$cred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $Session

1) Create a credential-object stored in the variable $cred

2) Create a new remote PowerShell session against the PowerShell endpoint for Exchange Online

3) Import the cmdlets available in the remote session


Before you attempt to connect, make sure that the PowerShell execution policy isn`t set to Restricted which is the default, as this will prevent the remote session from being loaded. A recommended approach is to use RemoteSigned which can be set by running Set-ExecutionPolicy RemoteSigned.

When the above steps are completed the cmdlets for managing Exchange Online is available in a script module:


To list the available cmdlets we can use Get-Command –Module tmp*:


Due to the fact that there is 290 cmdlets available when authenticating as a Office 365 global administrator the output above is truncated. Based on what RBAC-role the user is a member of, different cmdlets will be available.

A reference to the available cmdlets for administering Exchange Online is available here.


Microsoft Online Services Identity Federation Management

The Microsoft Online Services Identity Federation Management tool that was available in the Office 365 beta is now deprecated. The functionality of the tool is now integrated into the Microsoft Online Services Module for Windows PowerShell, which is used to configure Active Directory Federation Services 2.0 when deploying identity federation On-Premises. Instructions on how to manage federated domains is available here.


Microsoft Online Services Directory Synchronization tool

The Microsoft Online Services Directory Synchronization tool is used synchronize the On-Premises Active Directory environment with an Office 365 tenant. Instructions for setting up directory synchronization and installing the directory synchronization tool is available here.

Two Windows PowerShell snapins is installed as part of the Directory Synchronization tool:

  • Coexistence-Configuration
  • Coexistence-Install

There is no shortcuts to the snapins either on the Start-menu or the desktop. They can either be launched by using Add-PSSnapin or by launching the PowerShell Console-files in C:\Program Files\Microsoft Online Directory Sync:


The available cmdlets:


By default the Directory Syncronization Tool performs a delta sync every 3 hours. To perform a sync more often, or as part of a provisioning script, the Start-OnlineCoexistenceSync cmdlet can be invoked (no parameters needed).

The cmdlets available in the Coexistence-Install snapin is primarily needed when using a remote SQL Server database. By default a local SQL Express instance is used as the database, which scales up to approximately 50 000 objects. When the number of contacts, users and groups in the On-Premises Active Directory environment exceeds this limit, it`s recommended to configure the Directory Synchronization Tool to use a full version of SQL Server.


With the new offerings in Office 365 the ability to automate administration using Windows PowerShell is greatly enhanced compared to the previous version. The use of PowerShell remoting makes it a dynamic feature, as Microsoft can add more cmdlets without the need for administrators to download updated administration tools.

To my knowledge there will be no cmdlets available for administering Lync Online and Sharepoint Online when Office 365 is released for general availability, however, this may be a added in the future. This blog-post will be updated when more information on administering Office 365 using Windows PowerShell becomes available.


Update 22.05.2010: The blog-post is now updated to reflect the availability of the Microsoft Online Services Module for Windows PowerShell.

May 9, 2011 Posted by | Office 365, Windows PowerShell | , , | 15 Comments