Powershell

Getting AD User Data via PowerShell

It’s a common question asked of IT – “Can you give me a list of who’s in Marketing?” or “How many accounts do we actually have?”

Before PowerShell, this was a lot harder to do. There were companies like Quest Software who provided several handy tools (and still do) , or long complicated visual basic scripts.

So, how do you get a list of users? All of this is being done from the Active Directory Module for Windows PowerShell which will install as part of the Windows Server 2012 Feature – Role Administration Tools > AD DS and AD LDS Tools > Active Directory Module for Windows PowerShell.

The ‘Get-ADUser’ command is what we’ll use to demonstrate what you can do.

For starters, ‘Get-ADUser -filter*’ will get you a list of all users, and they’ll output in this format one after the other:

powershell1 (1)

A lot of information. You can specify a single user with:

Get-ADUser -identity username

which will just show you the one result.

As you may be aware, there are a lot more fields a user has than just the ones shown. You can tell PowerShell to show you all the properties by modifying the command like this:

Get-ADUser -identity username -properties *

Note that in PowerShell v4 if you get the error “get-aduser : One or more properties are invalid.” then there may be an issue with your schema. Check out this post for more information.

If there’s just one extra property you need, there’s no point getting everything, so if you needed to see a field such as “Department” for all users then adjust the command like this:

Get-ADUser -filter * -properties Department

Now, this gives the results for every single user in your Active Directory environment. You can narrow this down to a particular OU (and consequent sub OUs) by changing the command to this:

Get-ADUser -searchbase “ou=specialusers,ou=users,dc=mydomain,dc=com” -filter * -Properties Department

Now, you might be wondering how to get rid of all the standard properties and only see the ones you want.

There are two ways to pipe out the data that you want. One is with the ‘Format Table’ and the other is ‘Select Object’. Say you want a list of staff and their departments, we only need to use the ‘name’ field and the ‘department’ field.

Here’s what the two command look like, which are very similar:

Get-ADUser -searchbase “ou=specialusers,ou=users,dc=mydomain,dc=com” -filter * -Properties Department | ft name, department

Get-ADUser -searchbase “ou=specialusers,ou=users,dc=mydomain,dc=com” -filter * -Properties Department | Select-Object name, department

powershell2

The results of these commands will look exactly the same. But, when you want to export this information out, you would normally use the ‘Export-CSV’ command. If you use the ‘ft’ option, the results will not be what you expect. There is a brief writeup on this on the Windows PowerShell Blog which shows what you’ll see and explains why. The ‘Select Object’ command doesn’t have this issue.

So, if you want to output this list to a text file, here’s the command to use:

Get-ADUser -searchbase “ou=specialusers,ou=users,dc=mydomain,dc=com” -filter * -Properties Department | Select-Object name, department | export-csv c:\temp\myfile.csv

Note that you can also cheat and just pipe any output to a textfile using the old DOS redirect output method, which works even with the ‘ft’ option:

Get-ADUser -searchbase “ou=specialusers,ou=users,dc=mydomain,dc=com” -filter * -Properties Department | Select-Object name, department > c:\temp\myfile.csv

Note that one ‘>’ creates a new file or overwrites an existing, while a double ‘>>’ will create a new file or append to an existing.

Easy! Now you can provide Active Directory details to whomever asks, with a one line command that will output only the fields you want.

Password Expiry Notification Script

Going back to basics can often be a good solution to a problem. Emailing users letting them know that their password will expire soon is usually the most broad way of letting everyone know. If they are using ActiveSync only to get their emails, they won’t be notified when their password expires until it stops working.

With that in mind, I set out to find a simple script that runs daily, to let people know when their password is due to expire.

There’s a lot out there, but I wanted to use PowerShell and set it as a daily scheduled task.

Technet had a great one here from Johan Dahlbom. Except it didn’t work for me, as I recieved the error when testing:

get-aduser : One or more properties are invalid.

After some research, I found this blog post which had my exact issue. It seems that PowerShell v4 which comes with Windows 8.1 and Windows Server 2012 R2 doesn’t like the wildcard for -properties when running a get-aduser command, such as :

get-aduser -filter * -properties *

Richard Siddaway’s solution was to pipe it out and use get-object instead, but that doesn’t give all the same results as the original.

Instead I chose to specify the actual fields needed which turned the command into:

get-aduser -filter * -properties enabled, passwordneverexpires

That worked perfectly. So after adjusting a few parts of the script, I had it working.

I then decided that I didn’t want a daily email going out saying ‘You have 7 days” then “You have 6 days” etc, but just 2 variables – 7 days and 1 day.

So, here is the script (downloadable here: Password Change Notification)

#################################################
# Please Configure the following variables….
# expireindays1 + 2 = At what count of days left on a password do you want a notification?
$smtpServer=”smtp.yourmailserver.com”
$expireindays1 = 7
$expireindays2 = 1
$from = “Name <[email protected]>”
#################################################

#Get Users From AD who are enabled
Import-Module ActiveDirectory
$users = get-aduser -filter * -Properties enabled, passwordneverexpires, passwordexpired, emailaddress, passwordlastset |where {$_.Enabled -eq “True”} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }

foreach ($user in $users)
{
$Name = (Get-ADUser $user | foreach { $_.Name})
$emailaddress = $user.emailaddress
$passwordSetDate = (get-aduser $user -properties passwordlastset | foreach { $_.PasswordLastSet })
$PasswordPol = (Get-AduserResultantPasswordPolicy $user)
# Check for Fine Grained Password
if (($PasswordPol) -ne $null)
{
$maxPasswordAge = ($PasswordPol).MaxPasswordAge
}

else
{
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
}

$expireson = $passwordsetdate + $maxPasswordAge
$today = (get-date)
$daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
$subject=”Your password will expire in $daystoExpire days”
$body =”
Dear $name,
<p> Your password will expire in $daystoexpire day(s).<br>
To change your password, do these things<br>
For remote password changes, sign in to this address and change it there’ <br>
<p>Thanks, <br>
IT
</P>”

if (($daystoexpire -eq $expireindays1) -or ($daystoexpire -eq $expireindays2))
{
Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High

}

}

Powershell for Resource Information in Exchange 2010

Hi,

I came up against an issue today, where the person looking after calendar bookings for some newly created rooms (which was a resource) in Exchange 2010, could not see a lot of the information on the appointments. The subject had changed from whatever the person booking had written to their own name and the comments were missing. Coming from Exchange 2007 I hadn’t seen this before, but delved into the ‘Resource Inforamtion’ tab on one of the rooms. Rather quickly I realised this was happening by design, and the default options from Exchange:

Resource Information

 

So, for my scenario I wanted to remove most of these options, as we wanted the people with full access to the calendar to be able to see these things. I can understand having this disabled by default, as it’s really a business decision to make on who should see what. For me, I wanted to have the appointment unaltered which means removing “Delete attachments”, “Delete comments”, “Delete subject”, “Delete non-calendar items” and “Add the organizer’s name to the subject” (this one is just for less confusion, and you can still see the organiser from the attendees on the appointment itself). “Remove the private flag on an accepted meeting” I’d rather keep, if someone’s actually marking the meeting as private there’s hopefully a good reason.

Anyway, changing these options works perfectly, but doing it on a mass scale isn’t fun via the GUI. Powershell time!

I want to change this for all my Room Resources. First, you can get your list of Room Resources with this command:

Get-Mailbox -RecipientTypeDetails RoomMailbox

After confirming you see the results that you expect, you can pipe that into a command to turn off the required options. As a single command it would be this:

Set-CalendarProcessing -identity “Roomname” -DeleteAttachments $false -DeleteSubject $false -DeleteComments $false -DeleteNonCalendarItems $false -AddOrganizerToSubject $false

And merging the two together will be (dropping the -identity):

Get-Mailbox -RecipientTypeDetails RoomMailbox | Set-CalendarProcessing -DeleteAttachments $false -DeleteSubject $false -DeleteComments $false -DeleteNonCalendarItems $false -AddOrganizerToSubject $false

That’s it. All your rooms will now have the options you want. There’s a great article on MSExchange that covers this and a lot more: http://www.msexchange.org/articles-tutorials/exchange-server-2010/management-administration/resource-mailboxes-exchange-2010-part4.html and also has a table of the options on this screen and the relevant powershell parameter.

Good luck!

Setting Lync 2010 PINs via PowerShell

Hi,

I am currently in the process of rolling out Lync, and wanted an easy way to mass set everyone’s PIN number. Rather than setting everyone’s PIN to a single number, I wanted part of it based on their extension number. The solution I used was writing up the below PowerShell script to use in the Lync Server Management Shell.

So, why would you do this? When you want everyone to know what the PIN format is, and not accidently log in with the wrong extension due to typing it incorrectly once (they have to type it incorrectly twice).

This is what it does:

I had to import the activedirectory module because the get-csaduser command didn’t get the results as a string, meaning I couldn’t do the substring command on it.

Then, it get the two properties of officephone (needed for the pin) and the samaccount name (same as username in lync) from the users in the specified OU.

For each of those results, it sets the officephone number from Active Directory as the $phone variable, then it sets the last 3 digits of the $phone variable as the $ext variable and sets the samaccountname as the $username.

Finally it runs the set-CSClientPin command based on the username, setting the pin to 99 and the 3 digit extension.

 

You can’t set the pin to match the extension exactly as Lync will refuse to let you. You could modify this quite easily to just have everyone’s pin as 1234.

 

import-module activedirectory
$users = get-aduser -filter * -properties officephone,samaccountname -searchbase “ou=users,dc=yourdomain,dc=com,dc=au”

foreach ($user in $users)
{
$phone = $user.officephone
$ext = $phone.substring($phone.length -3,3)
$username = $user.samaccountname
Set-CsClientPin -identity $username -pin 99$ext
}

 

Happy Lyncing!