Monthly Archive

String startswith method

If you look at the methods available on a string one of them is StartsWith(). It tests if a given string starts with another string

 

£> 'frgrughrugu'.StartsWith

OverloadDefinitions
-------------------
bool StartsWith(string value)
bool StartsWith(string value, System.StringComparison comparisonType)
bool StartsWith(string value, bool ignoreCase, cultureinfo culture)

 

 

The first option is the easiest to use and the most common scenario

 

£> 'frgrughrugu'.StartsWith('frg')
True
£> 'frgrughrugu'.StartsWith('xya')
False

 

Unlike most things in PowerShell this comparison is NOT case insensitive

£> 'frgrughrugu'.StartsWith('fRg')
False

 

The second option helps by letting you use the members of the System.StringComparison enumeration to control the way the comparison is performed

 

£> $ct = [System.StringComparison]::CurrentCultureIgnoreCase

 

£> 'frgrughrugu'.StartsWith('frg', $ct)
True
£> 'frgrughrugu'.StartsWith('fRg', $ct)
True

 

The final option allows you to use a culture to control the way the comparison is performed. $null implies use the current culture. Note how the boolean controlling the case sensitivity works:

£> 'frgrughrugu'.StartsWith('frg', $true, $null)
True
£> 'frgrughrugu'.StartsWith('fRg', $true, $null)
True
£> 'frgrughrugu'.StartsWith('fRg', $false, $null)
False
£> 'frgrughrugu'.StartsWith('frg', $false, $null)
True

Domain Admins password last set

A recent question on the forums asked about getting the date a password was last set and the password never expires status for the domain admins group

This is one way of doing it

 

Get-ADGroupMember -Identity 'Domain Admins' |
foreach {
Get-ADUser -Identity $psitem.samAccountName -Properties PasswordLastSet, PasswordNeverExpires |
select Name, PasswordLastSet, PasswordNeverExpires
}

 

Get the group and for each member get the aduser information and select the properties to display.

 

Get-ADGroupMember and Get-AdUser work together on the pipeline so you can also do this:

 

Get-ADGroupMember -Identity 'Domain Admins' |
Get-ADUser -Properties PasswordLastSet, PasswordNeverExpires |
select Name, PasswordLastSet, PasswordNeverExpires

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