PowerShell for Windows Admins

June 26, 2015  2:10 PM

Basic LDAP filters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

I recently showed how to create an LDAP filter for an attribute that wasn’t set.  I thought it would be useful to show some other LDAP filters.

The examples are from a testing OU in my AD

£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -Filter * | select Name

Dave Green
Dave Brown
Dave White
Jo Daven
Fred Green
Dale Greensmith
Dave Greenly

Finding objects where an attribute matches a given value is probably the easiest:

£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -LDAPFilter ‘(sn=Green)’ | select Name

Dave Green
Fred Green

£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -LDAPFilter ‘(givenName=Dave)’ | select Name

Dave Green
Dave Brown
Dave White

You can also match on substrings

£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -LDAPFilter ‘(sn=Gre*)’ | select Name

Dave Green
Fred Green
Dave Greenly
Dale Greensmith

£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -LDAPFilter ‘(name=D*G*)’ | select Name

Dave Green
Dale Greensmith
Dave Greenly

You can also use an Ambiguous Name Resolution (ANR) filter which expands the filter to check a number of properties including:






sn (surname)

£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -LDAPFilter ‘(anr=Green)’ | select Name

Dave Green
Fred Green
Dale Greensmith
Dave Greenly

ANR is useful if you’re not sure what attributes to use but is a more expensive search option as you have to scan a number of attributes per object – indexed attributes help speed the process but its still quicker to hit a single attribute

Next time we’ll look at combining

June 24, 2015  1:47 PM

DSC resources

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

New DSC resources are available on the PowerShell gallery.  See


for details.

Note the comment about DSC resource kit will no longer be published as waves but will be updated on the PowerShell gallery as required.

There is also a post showing some examples of writing DSC resources against a singleton instance


June 23, 2015  2:46 PM

LDAP filter for a property that isn’t set

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

Filtering on a particular LDAP property is straight forward

Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -Filter {Title -eq ‘Boss’}

You can also use an LDAP filter

Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -Properties * -LDAPFilter ‘(Title=Boss)’

I prefer LDAP filters as I find them more powerful and the I can use them in the GUI tools.

I was recently asked how do I filter on  a property that isn’t set. That’s a bit more tricky as  AD  doesn’t store a value if the property isn’t set.

You can do this with an LDAP filter

Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -LDAPFilter ‘(!(Department=*))’  -Properties *

(Department=*) searches for accounts where department is set

(!(Department=*)) searches for accounts where its not set

Note that the filter is =*

You can’t use other characters

You can also check for multiple properties that aren’t set

Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’  -LDAPFilter ‘(&(!(Company=*))(!(Department=*)))’  -Properties *

The & in the filter means AND.  Note how the filter is constructed though with the individual filters after the &

June 16, 2015  2:01 PM

Service startup type

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell

Get-Service has been part of PowerShell since version 1. One thing it doesn’t do though is display the service startup type:

£> Get-Service | select -f 1 | fl *
Name                : 7f11b722
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : True
DisplayName         : AppendRunner
DependentServices   : {}
MachineName         : .
ServiceName         : 7f11b722
ServicesDependedOn  : {}
ServiceHandle       : SafeServiceHandle
Status              : Running
ServiceType         : Win32OwnProcess
Site                :
Container           :

You need to use the Win32_Service CIM class to get that information:

£> Get-CimInstance -ClassName Win32_Service -Filter “DisplayName = ‘AppendRunner'” | fl *
Name                    : 7f11b722
Status                  : Degraded
ExitCode                : 0
DesktopInteract         : False
ErrorControl            : Ignore
PathName                : “C:\windows\system32\rundll32.exe” “c:\Program Files
ServiceType             : Own Process
StartMode               : Auto
Caption                 : AppendRunner
Description             :
InstallDate             :
CreationClassName       : Win32_Service
Started                 : True
SystemCreationClassName : Win32_ComputerSystem
SystemName              : RSSURFACEPRO2
AcceptPause             : False
AcceptStop              : True
DisplayName             : AppendRunner
ServiceSpecificExitCode : 0
StartName               : LocalSystem
State                   : Running
TagId                   : 0
CheckPoint              : 0
ProcessId               : 1568
WaitHint                : 0
PSComputerName          :
CimClass                : root/cimv2:Win32_Service
CimInstanceProperties   : {Caption, Description, InstallDate, Name…}
CimSystemProperties     : Microsoft.Management.Infrastructure.CimSystemProperties

If you want to see the startup type for all services

Get-CimInstance -ClassName Win32_Service | Format-Table Name, DisplayName, State, StartMode –AutoSize

If you wan to group by start mode:

£> Get-CimInstance -ClassName Win32_Service | sort StartMode | Format-Table Name, DisplayName, State, StartMode -GroupBy
StartMode –AutoSize

The sort is essential otherwise a new group will be generated every time the start mode changes

June 2, 2015  7:44 AM

International module revisited

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A couple of years ago I wrote about the International module


I was recently asked about the availability of this module on Windows Server 2012 R2. I’ve found the module on all flavours of Windows 2012 r2 – server core and full GUI with and without the desktop experience

May 31, 2015  10:29 AM

Multiple expands

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell outputs objects but sometimes you need just the values. The –Expandproperty parameter of select-object can pull the values from a property.  Compare:

£> Get-VM | select Name



£> Get-VM | select -ExpandProperty Name

In the first you get an object with just a name property.  In the second you get just the name.

This is good BUT you can only expand a single property in one pipeline. If you need to expand multiple properties you need to do them individually and combine the results into a new object.  For instance to drill down into a 2012 r2 Hyper-V VM and get the IP addresses and the disk size

Get-VM |
foreach {
$props = [ordered]@{
Name = $($psitem.Name)
IPAddresses =  $psitem | select -ExpandProperty NetworkAdapters | select -ExpandProperty IPAddresses
DiskSize = [math]::Round((Get-ChildItem -Path ($psitem | select -ExpandProperty HardDrives | select -ExpandProperty path) | select -ExpandProperty Length) / 1GB, 2)
New-Object -TypeName PSObject -Property $props

The IP addresses are a simple double expansion.  The disk size you have to expand the harddrives, then the path  – get the file length and re-calculate the size to GB.

NOTE – I know all my VMs only have a single disk. If you have multiple disks you’ll need to build a loop to get all the sizes

May 31, 2015  8:23 AM

Finding users that can change their password

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

Way back in this post


I showed how to discover those users who can’t change their passwords. I was recently asked how to find those users that can change their password.

Active Directory doesn’t store this information directly but the CannotChangePassowrd attribute is  false for those users that can change their password

£> Get-ADUser -Identity richard -Properties CannotChangePassword
CannotChangePassword : False
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    : Richard@Manticore.org

So is you don’t mind using double negative logic you can find users that can change passwords like this:

Get-ADUser -Filter * -Properties CannotChangePassword |
where {-not $_.CannotChangePassword } |
Format-Table Name, DistinguishedName

I’ve restricted the properties brought back to the default ones plus CannotChangePassword


-not $_.CannotChangePassword

as a filter to determine the users that have the attribute set to false

You could also use

! $_.CannotChangePassword

but I prefer using –not as its easier to read

May 29, 2015  10:42 AM

IPAM: 2 Reading data

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Once you have your IPAM server configured you can start to read the data its collected.

If you are working against a remote IPAM server than you need to create a CIM session to that machine before doing anything else.

$cs = New-CimSession -ComputerName W12R2SUS

You can discover the domain you’re working against

£> Get-IpamDiscoveryDomain -CimSession $cs | fl
Name           : manticore.org
DiscoverDc     : True
DiscoverDns    : True
DiscoverDhcp   : True
PSComputerName : W12R2SUS

The IPAM server configuration

£> Get-IpamConfiguration -CimSession $cs | fl
Version            :
Port               : 48885
ProvisioningMethod : Manual
GpoPrefix          :
HMACKey            : System.Security.SecureString
PSComputerName     : W12R2SUS

The servers – DHCP, DNS and DCs that IPAM is aware of:

£> Get-IpamServerInventory -CimSession $cs
RecommendedAction   : IPAM Access Unblocked
ManageabilityStatus : Managed
IPAMAccessStatus    : Unblocked
ServerType          : {DC, DNS, DHCP}
ServerName          : server02
Name                : server02.Manticore.org
DnsSuffix           : Manticore.org
DomainName          : manticore.org
ServerStatus        : NoChange
DataRetrievalStatus : Completed
IPv4Address         : {}
IPv6Address         :
PSComputerName      : W12R2SUS

The address space

£> Get-IpamAddressSpace -CimSession $cs
Name                           : Default
Type                           : ProviderAddressSpace
Owner                          :
Description                    : Default Provider IP Address Space
AssociatedProviderAddressSpace :
Tenant                         :
VMNetwork                      :
IsolationMethod                :
Ipv4PercentageUtilized         : 3.44827586206896
Ipv6PercentageUtilized         : 0
CustomConfiguration            :
PSComputerName                 : W12R2SUS

Individual subnets

£> Get-IpamSubnet -CimSession $cs -AddressFamily IPv4
Name                 :
NetworkId            :
NetworkType          : NonVirtualized
Overlapping          : False
NetworkSite          :
VmmLogicalNetwork    :
ProviderAddressSpace : Default
CustomerAddressSpace :
VlanId               :
Owner                :
PSComputerName       : W12R2SUS

and the address ranges for those subnets

£> Get-IpamRange -CimSession $cs -AddressFamily IPv4
Overlapping      : False
NetworkID        :
StartIPAddress   :
EndIPAddress     :
ManagedByService : MS DHCP
ServiceInstance  : server02.Manticore.org
NetworkType      : NonVirtualized
Owner            :
PSComputerName   : W12R2SUS

May 28, 2015  1:39 PM

Copy files over PS remoting sessions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One neat feature of the April 2015 WMF 5.0 preview is that you can copy files over a remoting session.

First create a session to a remote machine

$cs = New-PSSession -ComputerName W12R2SUS

Define the source and destination for the copy.  Use –ToSession to determine the remoting session you will use to determine the remote machine

Copy-Item -Path C:\Source\test.csv -Destination C:\Source\test.csv -ToSession $cs

You use –FromSession to copy from a remote machine

Copy-Item -Path C:\Source\srv.csv -Destination C:\Source\srv.csv -FromSession $cs

What you can’t do is copy from one session to another

$cs2 = New-PSSession -ComputerName server02

£> Copy-Item -Path C:\Source\*.csv -Destination C:\Source\ -FromSession $cs2 -ToSession $cs
Copy-Item : ‘-FromSession’ and ‘-ToSession’ are mutually exclusive and cannot be specified at the same time.

May 27, 2015  12:30 PM

PowerShell Summit Europe 2015 – – sold out

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The PowerShell Summit Europe 2015 is sold out.  Please be aware that we don’t maintain a waiting list as the Summit is a benefit of  PowerShell Association membership

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: