PowerShell for Windows Admins


December 5, 2012  1:31 PM

Counting the members in an AD group



Posted by: Richard Siddaway
Active Directory, PowerShell

A question came up on the forum about counting the number of members a group has.  There are a number of ways of doing this but this is one of the easiest

$data = @()            
Get-ADGroup -Filter {Name -like "ADL*"} |            
foreach {            
 $data += New-Object -TypeName PSObject -Property @{            
   Name = $_.Name            
   MemberCount = (Get-ADGroupMember -Identity $($_.DistinguishedName) | Measure-Object ).Count            
 }            
}            
$data

Use the Get-ADGroupMember cmdlet and pipe the output to Measure-Object. Take the Count property.

BTW the forums I refer to are at powershell.org  If you haven’t visited I would strongly recommend you do.

December 3, 2012  4:58 PM

Comparing group membership



Posted by: Richard Siddaway
Active Directory, PowerShell, PowerShell 3

A question on the forum asked about comparing the memberships of two groups & displaying information about the users that are in both. The normal reaction is that you have to iterate through the two groups but then I remembered Compare-Object and came up with this

$group1 = Get-ADGroupMember -Identity ADL-group1 | select SamAccountName            
            
$group2 = Get-ADGroupMember -Identity ADL-group2 | select SamAccountName            
            
Compare-Object -ReferenceObject $group1 -DifferenceObject $group2 -IncludeEqual |             
where SideIndicator -eq "==" |            
foreach {            
 $sam = ($_.InputObject).SamAccountName             
             
 Get-ADUser -Identity $sam -Properties *            
            
}

Get the group membership of each group into a variable – I’m using the Microsoft cmdlets and just selecting the samaccountname to compare.

Using Compare-Object I used the –IncludeEqual parameter to make sure I got the matches and then filtered on the SideIndicator value of “==” .  That gets me the matches.

I then loop through them and use Get-ADUser to pull back the properties I need.

If you want to do this with the quest cmdlets use distinguished name instead of samaccountname


December 3, 2012  3:02 PM

How to give yourself an ulcer in one evening or why Word remains minimised on the Taskbar



Posted by: Richard Siddaway
Office 2013

I have just spent an extremely frustrating 3 hours trying to figure out why Word 2013 remained minimised on the task bar of my Windows 8 machine. Everything else opened up correctly including other Office applications such as Excel and PowerPoint.

I checked on other machines and it wasn’t the document I was trying to open – later found it was all Word documents – even those coming from my Skydrive.

Tried repairing Office – didn’t work

Looked through the registry – nothing

Tried opening Word through PowerShell – still minimised. Looked through the Word object – nothing.

Tried Internet searches – best option is to maximise through Task Manager – didn’t work. Tried move and size options – nothing.

Just had a brain wave. Yesterday I had an external monitor attached. Switched that on and there is Word in all its glory. Dragged the Window back to my laptop screen and everything works properly now.

So the moral of the story is don’t shut down word on an external monitor unless you want to give yourself an ulcer!


December 2, 2012  7:36 AM

PowerShell–jobs and scheduled tasks–date change



Posted by: Richard Siddaway
PowerShell, User Group

I’ve had to move the Live Meeting to Tuesday 11 December


When: Tuesday, Dec 11, 2012 7:30 PM (GMT)


Where:

*~*~*~*~*~*~*~*~*~*

PowerShell jobs provide the ability to perform long running background tasks. With the introduction of cmdlets to schedule tasks the possibilities increase

Notes


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: KRSN4M
    Entry Code: s`xS<XHp2
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.


December 2, 2012  5:39 AM

Defining Active Directory Identity with PowerShell



Posted by: Richard Siddaway
Active Directory, PowerShell

There are two sets of cmdlets for working with Active Directory – Microsoft and Quest. Unfortunately they offer slightly different options for defining the identity of the user you want to work with.

The Microsoft cmdlets offer these options:

Distinguished Name = "CN=GREEN Mike,CN=Users,DC=Manticore,DC=org"
GUID  = 53837835-1de0-4686-ae3f-b8cf23890ce3
Sid = S-1-5-21-3881460461-1879668979-35955009-6273
sAMAccountName = mgreen

By contrast the Quest cmdlets offer these options for defining Identity:

DN = DistinguishedName = "CN=GREEN Mike,CN=Users,DC=Manticore,DC=org"
SID = S-1-5-21-3881460461-1879668979-35955009-6273
GUID = 53837835-1de0-4686-ae3f-b8cf23890ce3
UPN = UserPrincipalName = mgreen@manticore.org
Domain\UserName = MANTICORE\mgreen

If you not using the cmdlets and relying on the ADSI interface – all you can use is the distinguished name

$user = [ADSI]”LDAP://CN=GREEN Mike,CN=Users,DC=Manticore,DC=org"


November 30, 2012  2:39 PM

A switch in time



Posted by: Richard Siddaway
PowerShell

I’ve posted about the switch statement a number of times but it is one of those topics that keeps coming up. Imagine you have a variable that can take one of several values. Depending on the value you might want to perform different actions like this

"red", "blue", "white", "black", "green", "yellow" |            
foreach {            
$colour = $_            
            
if ($colour -eq "red"){Write-host "Apples can be red"}            
if ($colour -eq "blue"){Write-host "Balloons can be blue"}            
if ($colour -eq "white"){Write-host "Snow can be white"}            
if ($colour -eq "black"){Write-host "Coal can be black"}            
if ($colour -eq "green"){Write-host "Grass can be green"}            
if ($colour -eq "yellow"){Write-host "Custard can be yellow"}            
}

This is a whimsical example but my excuse is that its been a long week. 

The code compares the variable to a number of values and when it finds a match something happens – in this case some text is printed.

This code works but it is overly verbose and each and every if statement is executed which is inefficient

The switch statement was designed for this situation where you need to perform multiple comparisons

"red", "blue", "white", "black", "green", "yellow" |            
foreach {            
switch ($_){            
 "red"    {Write-host "Apples can be red"}            
 "blue"   {Write-host "Balloons can be blue"}            
 "white"  {Write-host "Snow can be white"}            
 "black"  {Write-host "Coal can be black"}            
 "green"  {Write-host "Grass can be green"}            
 "yellow" {Write-host "Custard can be yellow"}            
} # end of switch            
} # end of foreach

You define the variable you will test – in this case $_

The possible values are listed and the actions to take define in the script block.

This can be improved – what if a colour isn’t defined in the switch statement.  In this case you use the default statement to catch it

"red", "blue", "white", "black", "green", "yellow", "cyan" |            
foreach {            
switch ($_){            
 "red"    {Write-host "Apples can be red"}            
 "blue"   {Write-host "Balloons can be blue"}            
 "white"  {Write-host "Snow can be white"}            
 "black"  {Write-host "Coal can be black"}            
 "green"  {Write-host "Grass can be green"}            
 "yellow" {Write-host "Custard can be yellow"}            
 default {Write-Host "can't process $($_)"}            
} # end of switch            
} # end of foreach

One final improvement is to make the switch statement terminate once its made a match.  if you did this

"red", "blue", "white", "black", "green", "yellow", "cyan" |            
foreach {            
switch ($_){            
 "red"    {Write-host "Apples can be red"}            
 "blue"   {Write-host "Balloons can be blue"}            
 "white"  {Write-host "Snow can be white"}            
 "black"  {Write-host "Coal can be black"}            
 "green"  {Write-host "Grass can be green"}            
 "blue"   {Write-host "Bikes can be blue"}            
 "yellow" {Write-host "Custard can be yellow"}            
 default {Write-Host "can't process $($_)"}            
} # end of switch            
} # end of foreach

but really you want to stop the comparison when you get a match so you use the break keyword

"red", "blue", "white", "black", "green", "yellow", "cyan" |            
foreach {            
switch ($_){            
 "red"    {Write-host "Apples can be red"; break}            
 "blue"   {Write-host "Balloons can be blue"; break}            
 "white"  {Write-host "Snow can be white"; break}            
 "black"  {Write-host "Coal can be black"; break}            
 "green"  {Write-host "Grass can be green"; break}            
 "blue"   {Write-host "Bikes can be blue"; break}            
 "yellow" {Write-host "Custard can be yellow"; break}            
 default {Write-Host "can't process $($_)"}            
} # end of switch            
} # end of foreach

In this case the second test on “blue” won’t happen

Switch can get a lot more complicated than this so I recommend you read the help file

get-help about_switch


November 30, 2012  11:46 AM

Active Directory & testing for user’s existence



Posted by: Richard Siddaway
Active Directory, PowerShell

 

When you are creating a new user you may want to test if a particular name is already is use. The Quest AD cmdlets provide great functionality but one area of confusion is where you are searching for a user by name:

PS> Get-QADUser -Identity "GREEN Dave" | ft -a

Name        Type DN
—-        —- —
GREEN Dave  user CN=GREEN Dave,CN=Users,DC=Manticore,DC=org
GREEN Dave2 user CN=GREEN Dave2,CN=Users,DC=Manticore,DC=org

But I didn’t ask for the second user. The problem is because the Quest cmdlets use s ANR – ambiguous name resolution when searching. This is equivalent to using "GREEN Dave*" in your search. In other words the cmdlets assume you are appending wildcards.

Way round it is to use an LDAP filter

PS> Get-QADUser -LdapFilter ‘(cn=GREEN Dave)’ | ft -a

Name       Type DN
—-       —- —
GREEN Dave user CN=GREEN Dave,CN=Users,DC=Manticore,DC=org

LDAP filters are also available with the Microsoft cmdlets (you can’t use name as a search with the identity parameter with the MS cmdlets)

PS> Get-ADUser -LdapFilter ‘(cn=GREEN Dave)’

DistinguishedName : CN=GREEN Dave,CN=Users,DC=Manticore,DC=org
Enabled           : True
GivenName         : Dave
Name              : GREEN Dave
ObjectClass       : user
ObjectGUID        : 28f0c168-d142-417f-a223-333488cdaa77
SamAccountName    : dgreen
SID               : S-1-5-21-3881460461-1879668979-35955009-6270
Surname           : GREEN
UserPrincipalName : dgreen@manticore.org

All of these alternatives will work

Get-ADUser -LdapFilter ‘(name=GREEN Dave)’
Get-QADUser -LdapFilter ‘(name=GREEN Dave)’
Get-QADUser -LdapFilter ‘(name=green dave)’
Get-ADUser -LdapFilter ‘(name=green dave)’

As an additional bonus with the Microsoft cmdlets you can write the filter using PowerShell syntax

Get-ADUser -Filter {name -eq ‘green dave’}

if you want to unambiguously resolve a name in an AD search – use an LDAP filter


November 28, 2012  10:44 AM

Clearing all telephone information for an AD account



Posted by: Richard Siddaway
Active Directory, PowerShell

I had a question through the blog asking how you could clear the telephone, pager and ipphone information from a user account.

Telephone information in AD appears on the General tab telephone and Other..   And on the telephone tab there is home, mobile, pager, fax and ipphone each of which can have a number of Other phone numbers added

I thought it best to write a function that clears all telephone information.  That way you can pick out the bits you need.

function clear-telephoneInfo {            
[CmdletBinding()]            
param (            
 [parameter(ParameterSetName="ByDN")]            
 [string]$dn,            
 [parameter(ParameterSetName="ByName")]            
 [string]$name,            
 [parameter(ParameterSetName="ByName")]            
 [string]$ou            
)            
switch ($psCmdlet.ParameterSetName) {            
 "ByDN"  {$distname = $dn }            
 "ByName"  {$distname = "cn=$name,$ou" }            
 default {Write-Host "Error!!! Should not be here" }            
}            
            
## clear telephone from General tab            
$user = [adsi]"LDAP://$distname"            
$user.TelephoneNumber = ' '            
$user.otherTelephone = ' '            
$user.SetInfo()             
            
## clear Telephone tab            
## Home Phone            
$user = [adsi]"LDAP://$distname"            
$user.homePhone = ' '            
$user.otherHomePhone = ' '            
$user.SetInfo()             
            
## Pager            
$user = [adsi]"LDAP://$distname"            
$user.pager = ' '            
$user.otherPager = ' '            
$user.SetInfo()              
            
## Mobile            
$user = [adsi]"LDAP://$distname"            
$user.mobile = ' '            
$user.otherMobile = ' '            
$user.SetInfo()              
             
## Fax            
$user = [adsi]"LDAP://$distname"            
$user.facsimileTelephoneNumber = ' '            
$user.otherFacsimileTelephoneNumber = ' '            
$user.SetInfo()              
            
## Fax            
$user = [adsi]"LDAP://$distname"            
$user.ipPhone = ' '            
$user.otherIpPhone = ' '            
$user.SetInfo()            
            
## Notes            
$user = [adsi]"LDAP://$distname"            
$user.info = ' '            
$user.SetInfo()              
}

I created two parameter sets – one for the distinguished name (ByDN) and one where the name and OU are supplied.

The $distname parameter is set based on the parameter set.

An ADSI call gets the user; the telephoneNumber and othertelephone attributes are set to blank strings and the SetInfo() is called to write the changes back.

This is repeated for the other types of phone number and the Notes field on the telephone tab

I broke it up like this to make it easier to pick and choose what you need.  It would be possible to add more parameters to only pick off a particular type of phone number


November 26, 2012  2:27 PM

UK PowerShell group – December 2012



Posted by: Richard Siddaway
PowerShell 3, User Group

Last meeting of 2012 – PowerShell jobs and scheduled tasks

 


When: Tuesday, Dec 4, 2012 7:30 PM (GMT)


Where:

*~*~*~*~*~*~*~*~*~*

PowerShell jobs provide the ability to perform long running background tasks. With the introduction of cmdlets to schedule tasks the possibilities increase

Notes


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: KRSN4M
    Entry Code: s`xS<XHp2
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.


November 25, 2012  5:51 AM

Powershell Resources



Posted by: Richard Siddaway
PowerShell, User Group

I’ve reorganised the slide packs and recordings for the UK PowerShell group. You can find them here

https://skydrive.live.com/?cid=43cfa46a74cf3e96!cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%2139273

Three folders:

  • Events – slides from events I’ve spoken at
  • Scripts
  • UK PowerShell Group
  •        Meeting Recordings – includes slide packs
  •        Slide packs – from older meetings where the recording isn’t available

Enjoy


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: