Monthly Archive


Monthly Archives: December 2014

PowerShell Summit NA 2015

We will be getting extra capacity for the PowerShell Summit NA 2015 in Charlotte. The extra places should become available 11 January 2015 – see


for details. 

Please check the site for further news

PowerShell review of 2014

See my review of 2014 from a PowerShell perspective on the Scripting Guy blog -

More on dates

My recent post on date conversions seems to have generated a fair bit of confusion and discussion. The original task was to read in a string from a CSV file that contained a date in UK format – DD/MM/YYYY and reformat it to a string is US format – MM/DD/YYYY


As I showed you can’t use [datetime] type accelerator for this as it expects the date string to be in US format.


A number of people pointed out that you can use the –Date parameter on Get-Date

£> $strUK = '25/12/2014'
£> Get-Date -Date $strUK

25 December 2014 00:00:00


Now if you want that output as a string in US format

£> Get-Date -Date $strUK -Format "MM/dd/yyyy"


Use a variable to contain that data and you can work with it as you wish.


You need to be aware that using –Date on Get-Date is culture aware:

£> Get-Date -Date '25/12/2014'

25 December 2014 00:00:00

£> Get-Date -Date '12/25/2014'
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "12/25/2014" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:1 char:16
+ Get-Date -Date '12/25/2014'
+                ~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

ANR and AD searches

A comment on this post -

suggested using ANR – Ambiguous Name Resolution as a method of searching AD.


ANR provides a fuzzy search mechanism for AD – think wildcard search. If you perform an ANR search you’ll get anything matches – using your input as the root of the wildcard search – across display name, given name, name, samaccountname and surname.


Consider the searches shown last time based on the name Dave Green. Lets perform a ANR search on the first name

£> Get-ADUser -Filter {anr -eq 'Dave'} | select Name

Jo Daven
Dave Green
Dave Brown
Dave White

Get-ADUser -LDAPFilter "(anr=Dave)" | select Name

will give the same result.  In my AD I get 3 results. Any account where any of the names listed above that start with the letters ‘Dave’  will be returned. Notice that in one of the results the letters are in the surname not the first name.


Similar issues if you perform ANR searches based on surname

£> Get-ADUser -LDAPFilter "(anr=Green)" | select Name

Dave Green
Fred Green
Dale Greensmith


Get-ADUser -Filter {anr -eq 'Green'} | select Name


This time notice that the surname Greensmith is returned as well as Green.


You could use the whole name:

£> Get-ADUser -LDAPFilter "(anr=Dave Green)" | select Name


£> Get-ADUser -Filter {anr -eq 'Dave Green'} | select Name

Dave Green
Dave Greenly


NOTE: I created the Dave Greenly account after the previous searches which is why it didn’t show earlier.


ANR searches are also slower than searching on specific attributes because a number of properties are being searched.


An ANR search is a good first step if  you’re not sure what you’re looking for but you will usually need to refine the search using –Identity parameter or more specific filters if you if you want to get to a single object.

Using GivenName and Surname instead of samAccountName

A recent comment on this post - – asked about using the given name and surname rather than the samAccountName in Get-ADUser.

Get-ADUser has 4 options when using the –Identity parameter:

Account name = samAccountNmae

Distinguished Name


Security identifier = SID.

Using the given name and surname. on the surface doesn’t seem possible BUT (and there’s always a but with PowerShell) you can use the –Filter or –LDAPFilter parameters.


Where you know the samAcccountName you can do this:

Get-ADUser -Identity gdreen


Working with the names you could try this:

Get-ADUser -Filter {GivenName -eq 'Dave' -and Surname -eq 'Green'}


Alternatively, you could use an LDAP filter:

Get-ADUser -LDAPFilter "(&(GivenName=Dave)(Sn=Green))"


The LDAP syntax is a bit more complex but you can parse it as

(GivenName=Dave) AND (Sn=Green)

You have to use the LDAP name, Sn, for the Surname property rather than the more friendly property name that the –Filter parameter allows.


If you wanted to modify the code in the original article to use this approach:

$users = Import-Csv -Path C:\Scripts\adtest.csv           
foreach ($user in $users) {           
$fname = $user.GivenName
$lname = $user.Surname
Get-ADUser -Filter {GivenName -eq $fname  -and Surname -eq $lname} -Properties * |           
select SamAccountName, Division, Office, City            


I’ve found that its easier to substitute variables into the filter rather than try and and use the object from the CSV file directly.


The LDAP filter version would be

$users = Import-Csv -Path C:\Scripts\adtest.csv           
foreach ($user in $users) {           
Get-ADUser -LDAPFilter "(&(GivenName=$($user.GivenName))(Sn=$($user.Surname)))" -Properties * |            
select SamAccountName, Division, Office, City            


In this case you’re substituting into a string and it works quite nicely.

Date conversions

Saw a question regarding the conversion of dates in UK format DD/MM/YYYY to US format MM/DD/YYYY


Using 25 December 2014 as an example

If you have a dat in US format you can do this

£> $sd = '12/25/2014'
£> $d = [datetime]$sd
£> $d

25 December 2014 00:00:00


$d = [datetime]$sd   creates a datetime object


If you try that in UK format

£> $sduk = '25/12/2014'
£> $d = [datetime]$sduk
Cannot convert value "25/12/2014" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:1 char:1
+ $d = [datetime]$sduk
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider


It fails.

.NET expects strings representing dates to be in US format.

£> [datetime]'25 December 2014'

25 December 2014 00:00:00

works but the data isn’t in that format.


The easiest way I know to create a date object when you have UK format strings would be:

£> $sd = '25/12/2014' -split '/'
£> $sd
£> $d = Get-Date -Day $sd[0] -Month $sd[1] -Year $sd[2]
£> $d

25 December 2014 18:36:05

Merry Christmas from the PowerShell team

The PowerShell team have produced wave 9 of the DSc resource kit – just in time for Christmas -

This wave contains a number of new resources and some updates to existing resources including the Exchange resource.

You can download the latest version of the resource kit from

The team’s blog post states that you should check for the GA update (which is minimum requirement for running the DSC res kit) by testing to see if KB2883200 is installed. This won’t work if you’ve built you system using Windows media that incorporates the update.

A better test is to look at the build number. It should be 9400 or higher. You can see this by using $psversiontable

£> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      4.0
WSManStackVersion              3.0
CLRVersion                     4.0.30319.34014
BuildVersion                   6.3.9600.17400
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion      2.2

The version is  6.3.9600.17400  where 6.3 = Windows 2012 R2 and 9600 = the build

You can also use WMI

£> Get-CimInstance -ClassName Win32_Operatingsystem | Format-List BuildNumber, Version

BuildNumber : 9600
Version     : 6.3.9600

European Summit 2015 call for topics #2

The call for topics for the European PowerShell Summit is still open -

Please submit your topics by the deadline of 11 January 2015.


A few people have suggested subjects for topics they would like to see:

Azure automation with SAM and/or workflows

SCCM advanced scripting

DSC advanced scripting


Test Driven Deployment with Pester

Deep dive integration of .NET and Win32API with PowerShell


Could you provide a session on one of these or another topic?

We will have a number of established speakers and PowerShell personalities attending but at all of the Summits we like to take the opportunity to encourage new speakers.


If you’re not sure of a topic’s suitability or whether you should submit please get in touch and I’ll be happy to discuss

Delivering PowerShell code with the November preview

Step one of investigating OneGet and PowerShellGet – install the latest preview.  I have the environment I used for the demos at the European PowerShell Summit with a machine set up for DSC. Its currently running the September preview:

£> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.0.9814.0
WSManStackVersion              3.0
CLRVersion                     4.0.30319.34014
BuildVersion                   6.4.9814.0
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.2


The November preview is supposed to install over the top of the September preview. I’m installing on to  Windows 2012 R2 so I want:


The target machine is fully patched apart from the November Windows 2012 R2 roll up.

Installation occurred with out a problem. – I like the change to being able to just install over the top of pervious versions.  After the usual restart the version has changed.

£> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.0.9883.0
WSManStackVersion              3.0
CLRVersion                     4.0.30319.34014
BuildVersion                   6.4.9883.0
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.2


The PowerShellGet module contains these cmdlets:



The module type is Script meaning it contains PowerShell Advanced functions.  You can see the code at C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerShellGet


Just make sure you don’t change anything.


First thing is to see what repositories we’ve got:

£> Get-PSRepository | fl

Name               : PSGallery
SourceLocation     :
Trusted            : False
Registered         : True
InstallationPolicy : Untrusted
OneGetProvider     : NuGet
PublishLocation    :
ProviderOptions    : {}

Name               : MSPSGallery
SourceLocation     :
Trusted            : True
Registered         : True
InstallationPolicy : Trusted
OneGetProvider     : NuGet
PublishLocation    :
ProviderOptions    : {}


Notice that PSGallery is not trusted but MSPSGallery is trusted.

If you want to see the modules available use Find-Module.  

The first time you do expect this:

£> Find-Module

NuGet-anycpu.exe is required to continue.
PowerShellGet requires NuGet-anycpu.exe to interact with NuGet based galleries. NuGet-anycpu.exe must be available in
'C:\Program Files\OneGet\ProviderAssemblies' or 'C:\Users\Richard\AppData\Local\OneGet\ProviderAssemblies'. For more
information about NuGet provider, see Do you want PowerShellGet to download
NuGet-anycpu.exe now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"):


You’re going to have to download the nuget file to continue.


On many modules I get this error:

Cannot convert value "18/12/2014 04:22:19 +00:00" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PowerShellGet\PSGet.psm1:1402 char:49
+ ...               PublishedDate = if($published){ [DateTime]$published };
+                                                   ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider


If you use:

Find-Module -ErrorAction SilentlyContinue

You will get a display like this:

Version  Name           Repository Description
-------   ----                ---------- -----------
1.0.0      xFirefox       PSGallery  Firefox Main module
1.0.0      xChrome      PSGallery  Module for installing the chrome xJea              PSGallery  Module with DSC Resources for  (JEA)

and many more.


The date related error isn’t consistent - for instance the Pester module:

£> Find-Module -Name Pester | fl *

Name                       : Pester
Version                    : 3.2.0
Description                : Pester provides a framework for running BDD style Tests to execute and validate PowerShell commands inside of PowerShell and offers a powerful set of Mocking Functions that allow tests to mimic and mock the functionality of any command inside of a piece of powershell code being tested. Pester tests can execute any command or script that is accesible to a pester test file. This can include functions, Cmdlets, Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the
Build scripts of a Continuous Integration system.
Author                     : Pester Team
CompanyName                :
Copyright                  : Copyright (c) 2014 by Pester Team, licensed under Apache 2.0 License.
PublishedDate              : 12/03/2014 17:38:11
LicenseUri                 :
ProjectUri                 :
IconUri                    :
Tags                       : {powershell, unit, testing, bdd...}
Includes                   : {Function, DscResource, Cmdlet, Command}
PowerShellGetFormatVersion :
ReleaseNotes               :
RequiredModules            :
RepositorySourceLocation   :
Repository                 : PSGallery
OneGetProvider             : NuGet


But looking at the Pester module in the PowerShell gallery - – it shows a date of 2014-12-03  i.e. 3 December 2014.  My system is interpreting that as 12 March 2014 because I’m using the English convention for dates in my culture settings.

£> $PSCulture
£> $PSUICulture



Set-Culture -CultureInfo en-US


Restarting PowerShell then running

£> $PSCulture
£> Find-Module

Stops the error messages so


Find-Module | select Name, Version, PublishedDate

works. Just remember your dates are in US format – Month/Day/Year


The last step is downloading and installing a module. The Install-Module cmdlet does that for us.

£> Get-Command Install-Module -Syntax

Install-Module [-Name] <string[]> [-MinimumVersion <version>] [-RequiredVersion <version>] [-Repository <string[]>]
[-Scope <string>] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]

Install-Module [-InputObject] <psobject[]> [-Scope <string>] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]


Notice that there isn’t a choice of destination. You

£> Install-Module -Name Pester

You are installing the module 'Pester' from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet.
Are you sure you want to install software from ''?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y


This installs the module:

> Get-Module -ListAvailable p*

   Directory: C:\Program Files\WindowsPowerShell\Modules

oduleType Version    Name                                ExportedCommands
--------- -------    ----                                ----------------
cript     3.2.0      Pester                              {Describe, Context, It, Should...}


C:\Program Files\WindowsPowerShell\Modules was added to the modules path in PowerShell 4.0 and is the default location for DSC resources.


£> Install-Module -Name Pester –Force

Will override the message asking for confirmation.

Selecting AD properties

Saw a question on the forums about selecting name properties using the Microsoft AD cmdlets.  By default Get-AdUser returns a limited subset of properties:

£> Get-ADUser -identity richard

DistinguishedName : CN=Richard,CN=Users,DC=Manticore,DC=org
Enabled           : True
GivenName         :
Name              : Richard
ObjectClass       : user
ObjectGUID        : 7c42be70-c6b2-401f-8296-46de9ee7446c
SamAccountName    : Richard
SID               : S-1-5-21-195014076-723736408-1406369008-1104
Surname           :
UserPrincipalName :


Given name = first name


if you want other properties you have to explicitly aske for them using the –Properties parameter. You can use a wildcard * but if you have a big AD that could be a lot of unrequired data you are pulling back. On the other hand if you want a lot of properties its often simpler to use the wildcard. As with most PowerShell related things there is no answer that is right all of the time.


The user asking the question wanted the first name, last name and department for all users in a given OU.  Use the OU as the –SearchBase.  The property you need to explicitly ask for is Department:

£> Get-ADUser -Filter *  -SearchBase 'OU=Testing,DC=Manticore,DC=org' -Properties Department | select GivenName, SurName, Department | fl *

GivenName  : Dave
SurName    : Green
Department : Testing


Selecting AD properties can be a little bit awkward if you forget that the default set is limited.  If in doubt of a property name – display them all for one user:

Get-ADUser -identity richard -Properties *