Removing HomeDrive and HomeFolder settings
Back in this post https://richardspowershellblog.wordpress.com/wp-admin/post.php?post=2343&action=edit I showed how to set the users home directory and home drive.
I was recently asked how to remove entries from those attributes.
The easiest way is to use the –Clear parameter with set-AdUser
Set-ADUser -Identity gdreen -Clear HomeDrive, HomeDirectory
CIM filters
I was looking up Win32_SystemDriver on the MSDN site and noticed there was some PowerShell example code
Get-WmiObject -Class Win32_SystemDriver |
Where-Object -FilterScript {$_.State -eq "Running"} |
Where-Object -FilterScript {$_.StartMode -eq "Manual"} |
Format-Table -Property Name,DisplayName
A better way to write this would be:
Get-WmiObject -Class Win32_SystemDriver -Filter "State='Running' AND StartMode='Manual'" | Format-Table -Property Name, DisplayName –AutoSize
or
Get-CimInstance -ClassName Win32_SystemDriver -Filter "State='Running' AND StartMode='Manual'" | Format-Table -Property Name, DisplayName -AutoSize
Do the filtering in the CIM call – especially if you’re running this against a number of remote machines. That way you limit the network traffic you’re returning
Parsing ipconfig /displaydns with regular expressions
In yesterdays post I used a series of split operations to parse the strings produced by ipconfig /displaydns
Regular expressions should give a more power full way to perform this task. Not being a big fan of regular expressions I tend not to use them but for the sake of experimentation I thought I’d try and figure out a set of regex to use.
This is as far as I’ve got
$props = [ordered]@{
RecordName = ""
RecordType = ""
Section = ""
TimeToLive = 0
DataLength = 0
Data = ""
}
$recs = @()
$cache = ipconfig /displaydns
for($i=0; $i -le ($cache.Count -1); $i++) {
if ($cache[$i] -like '*Record Name*'){
$rec = New-Object -TypeName psobject -Property $props
$rec.RecordName = $cache[$i] -replace "(\s*\w*){2}(\s\.){5}(\s\:\s)", ""
$rec.Section = $cache[$i+4] -replace "\s*\w*(\s\.){7}(\s\:\s)", ""
$rec.TimeToLive = $cache[$i+2] -replace "(\s*\w*){3}\s(\s\.){4}(\s\:\s)", ""
$rec.DataLength = $cache[$i+3] -replace "(\s*\w*){2}(\s\.){5}(\s\:\s)", ""
$irec = ($cache[$i+5] -split ": ")
$rec.RecordType = ($irec[0].TrimStart() -split ' ')[0]
$rec.Data = $irec[1]
$recs += $rec
}
else {
continue
}
}
$recs | Format-Table –AutoSize
I still need to work out how to process the data and record type using regular expressions
Parsing ipconfig /displaydns
A recent question on the forum asked how you could get the contents on Windows 7 machines and earlier.
On later machines – Windows 8 and above - its easy because you can use Get-DnsClientCache from the DnsClient module. This module is based on CIM classes that aren’t present on Windows 7 and earlier systems.
You can use ipconfig /displaydns to display the data but it looks like this
Record Name . . . . . : ns-nw.noaa.gov
Record Type . . . . . : 1
Time To Live . . . . : 81966
Data Length . . . . . : 4
Section . . . . . . . : Additional
A (Host) Record . . . : 161.55.32.2
so you need to parse the strings into a format that you can work with.
This is one solution
$props = [ordered]@{
RecordName = ""
RecordType = ""
Section = ""
TimeToLive = 0
DataLength = 0
Data = ""
}
$recs = @()
$cache = ipconfig /displaydns
for($i=0; $i -le ($cache.Count -1); $i++) {
if ($cache[$i] -like '*Record Name*'){
$rec = New-Object -TypeName psobject -Property $props
$rec.RecordName = ($cache[$i] -split -split ": ")[1]
$rec.Section = ($cache[$i+4] -split -split ": ")[1]
$rec.TimeToLive = ($cache[$i+2] -split -split ": ")[1]
$rec.DataLength = ($cache[$i+3] -split -split ": ")[1]
$irec = ($cache[$i+5] -split ": ")
$rec.RecordType = ($irec[0].TrimStart() -split ' ')[0]
$rec.Data = $irec[1]
$recs += $rec
}
else {
continue
}
}
$recs | Format-Table –AutoSize
Create an ordered hash table of output properties and an empty array to hold the results.
Get the output of ipconfig /displaydns into $cache which will be an array of strings
Loop through $cache
if the record is like *Record Name*' then process that record and the next five records to give the results. The actual data record is split twice to give the record type and the data – otherwise you’ll have to translate the numeric values in the Record Type line.
The results are put into an object which is added to the output array.
Continue looping through $cache until you meet the next line with a Record Name or end of file.
Finally display the results.
This works but is messy – I’m going to investigate alternatives
Scripting Games
See what’s happening with the Scripting Games - http://blogs.technet.com/b/heyscriptingguy/archive/2015/06/27/powershell-spotlight-yeah-it-s-the-scripting-games.aspx
Thank about the requirements and offer to help as outlined in the article.
Multiple LDAP filters
Continuing our look at LDAP filters – remember the data set in use:
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -Filter * | select Name
Name
----
Dave Green
Dave Brown
Dave White
Jo Daven
Fred Green
Dale Greensmith
Dave Greenly
Individual filters work like this
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -LDAPFilter '(givenName=Fred)' | select Name
Name
----
Fred Green
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -LDAPFilter '(sn=Green)' | select Name
Name
----
Dave Green
Fred Green
You have two options for joining filters:
AND – uses & symbol
OR – uses | symbol
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -LDAPFilter '(&(givenName=Fred)(sn=Green))' |
select Name
Name
----
Fred Green
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -LDAPFilter '(|(givenName=Fred)(sn=Green))' |
select Name
Name
----
Dave Green
Fred Green
AD module cmdlets accepting LDAPfilter
In case you were wondering which cmdlets in the Active Directory module allowed you to use LDAP filters
£> Get-Command -Module ActiveDirectory -ParameterName LDapFilter
Name
----
Get-ADAuthenticationPolicy
Get-ADAuthenticationPolicySilo
Get-ADCentralAccessPolicy
Get-ADCentralAccessRule
Get-ADClaimTransformPolicy
Get-ADClaimType
Get-ADComputer
Get-ADFineGrainedPasswordPolicy
Get-ADGroup
Get-ADObject
Get-ADOptionalFeature
Get-ADOrganizationalUnit
Get-ADResourceProperty
Get-ADResourcePropertyList
Get-ADResourcePropertyValueType
Get-ADServiceAccount
Get-ADTrust
Get-ADUser
Basic LDAP filters
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
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
Name
----
Dave Green
Fred Green
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -LDAPFilter '(givenName=Dave)' | select Name
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
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
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:
displayname
givenname
proxyaddress
name
samaccountname
sn (surname)
£> Get-ADUser -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties * -LDAPFilter '(anr=Green)' | select Name
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
DSC resources
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
LDAP filter for a property that isn’t set
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 &