Blog view of all posts

Export a list over all disabled user accounts in Active Directory to CSV

This will export data in the following order (with scandinavian letters)
Givenname, Surname, SamAccountname, PrimarySMTPAddress

Get-QADUser -sizelimit 0 | where {$_.accountisdisabled -eq $true} | select givenname,sn,SamAccountName,PrimarySMTPAddress | Export-Csv -Encoding utf8 c:\temp\disabled_users.csv


Delete all empty subdirectories

(Get-ChildItem -recurse | Where-Object {$_.PSIsContainer -eq $True}) |
Where-Object {$_.GetFiles().Count -eq 0} | remove-item

UPDATE:
Chad Rexin has corrected this code:
(Get-ChildItem -recurse | Where-Object {$_.PSIsContainer -eq $True}) |
Where-Object {$_.GetFiles().Count -eq 0 -AND $_.GetDirectories().Count -eq 0} |
ForEach-Object {Write-Host “Deleting this empty directory $($_.FullName)”;
remove-item $_.FullName}

See below for discussion.


Import a list of users and export a list with more fields

# Make utf8 to include special characters
cat .\list.csv > .\list2.csv

# Import the file and process export as utf8
Import-Csv .\list2.csv | foreach {
Get-QADUser -lastname $_.lastname -firstname $_.firstname | select firstname,lastname,mobile,primarysmtpaddress,logonname
} | Export-Csv .\list3.csv -Encoding “UTF8″


Clean up user accounts in one OU after linked-mailbox migration to new domain

This script uses the Quest AD Cmdlets that can be downloaded free from Quest.

# Add the Quest commandlets if not added 
if(!(Get-PSSnapin | 
    Where-Object {$_.name -eq "quest.activeroles.admanagement"})) {
      ADD-PSSnapin Quest.Activeroles.ADManagement
    }
 
# Add Exchange 2010 commandlets (if not added)
if(!(Get-PSSnapin | 
    Where-Object {$_.name -eq "Microsoft.Exchange.Management.PowerShell.E2010"})) {
      ADD-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
    }
 
################## SETTINGS
# Home directory for users
$homedir = "\\contoso.com\users\"
 
# Domain
$domain = "contoso.com"
 
# Email address to keep
$keepmail = "@contoso.com"
 
# The OU we are working on
$OU = "contoso.com/Users/migrated_users"
##################
 
# Run on all users in the defined OU
Get-QADUser -SearchRoot $OU | 
foreach {
    echo "-------------------------------------------------"    
    echo "Working on $($_.displayname)"
    echo "-------------------------------------------------"
 
    # Generate username after the 3+3 rule
    $userprincipalname = ($_.firstname.substring(0,3) + $_.lastname.substring(0,3)).tolower()
    $userprincipalname = $userprincipalname.replace("ø","o")
    $userprincipalname = $userprincipalname.replace("å","a")
    $userprincipalname = $userprincipalname.replace("æ","e")
 
    # Make the changes on the user account
    Set-QADUser -Identity $_ -UserPrincipalName $($userprincipalname + "@" + $domain) -SamAccountName "$($userprincipalname)" -HomeDirectory $($homedir + $userprincipalname) -HomeDrive "H:"  #-whatif
 
    # Check to see if the users homedirectory exists
    if ( !(Test-Path -Path "$homedir\$userprincipalname" -PathType Container) ) {
 
         # Doesn't exist so create it.
         Write-Host "home directory doesn't exist. Creating home directory."
 
         # Create the directory
         New-Item -path $homedir -Name $userprincipalname -ItemType Directory
         $userDir = "$homedir\$userprincipalname"
 
         # Modify  Permissions on homedir
         $Rights= [System.Security.AccessControl.FileSystemRights]::Read -bor [System.Security.AccessControl.FileSystemRights]::Write -bor [System.Security.AccessControl.FileSystemRights]::Modify -bor [System.Security.AccessControl.FileSystemRights]::FullControl
         $Inherit=[System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
         $Propogation=[System.Security.AccessControl.PropagationFlags]::None
         $Access=[System.Security.AccessControl.AccessControlType]::Allow
         $AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule("$userprincipalname",$Rights,$Inherit,$Propogation,$Access)
         $ACL = Get-Acl $userDir
         $ACL.AddAccessRule($AccessRule)
         $Account = new-object system.security.principal.ntaccount($userprincipalname)
         $ACL.setowner($Account)
         $ACL.SetAccessRule($AccessRule)
         Set-Acl $userDir $ACL
    }
 
    # We need some sleep...
    start-sleep -sec 20
 
    # Now we need to clean up the users Exchange account
    Get-Mailbox -Identity $userprincipalname |
 
    # Loop through all the emailaddresses
    foreach { 
       $a = $_.emailaddresses
       $b = $_.emailaddresses
 
     # Remove all but $keepmail
       foreach($e in $a) 
           { 
           if ($e.tostring() -notmatch $keepmail ) 
               { $b -= $e; } 
           $_ | Set-mailbox -EmailAddressPolicyEnabled $false -emailaddresses $b -alias $userprincipalname
           }
    }
 
    # We had to remove the emailaddresspolicy to make changes. Let's reactivate it
    Set-mailbox -Identity $userprincipalname -EmailAddressPolicyEnabled $true
}

Delete all email addresses but one on a mailbox

  Get-Mailbox -Identity $userprincipalname |
 
    # Loop through all the emailaddresses
    foreach { 
       $a = $_.emailaddresses
       $b = $_.emailaddresses
 
     # Remove all but $keepmail
       foreach($e in $a) 
           { 
           if ($e.tostring() -notmatch $keepmail ) 
               { $b -= $e; } 
           $_ | Set-mailbox -EmailAddressPolicyEnabled $false -emailaddresses $b -alias $userprincipalname
           }
    }
 
    # We had to remove the emailaddresspolicy to make changes. Let's reactivate it
    Set-mailbox -Identity $userprincipalname -EmailAddressPolicyEnabled $true
}

Easier ForEach/Where-Object in Powershell V3

PowerTip of the Day, from PowerShell.com

In the upcoming PowerShell v3 which you can already download as a Beta version, using Where-Object and ForEach-Object becomes a lot simpler. No longer do you need a script block and code. This, for example, is all you need to find files larger than 1MB:

Get-ChildItem $env:windir | Where-Object Length -gt 1MB

Previously, you would have had to write:

Get-ChildItem $env:windir | Where-Object { $_.Length -gt 1MB }

Creating home directory for user

When setting the -homedirectory switch on a user through Powershell the directory is not created.
Use this code to create the folder and apply the necessary ACLs:

    if ( !(Test-Path -Path "$homedir\$userprincipalname" -PathType Container) ) {
         ## Doesn't exist so create it.
         Write-Host "home directory doesn't exist. Creating home directory."
 
         ## Create the directory
         New-Item -path $homedir -Name $userprincipalname -ItemType Directory
         $userDir = "$homedir\$userprincipalname"
 
         ## Modify  Permissions on homedir
         $Rights= [System.Security.AccessControl.FileSystemRights]::Read -bor [System.Security.AccessControl.FileSystemRights]::Write -bor [System.Security.AccessControl.FileSystemRights]::Modify -bor [System.Security.AccessControl.FileSystemRights]::FullControl
         $Inherit=[System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
         $Propogation=[System.Security.AccessControl.PropagationFlags]::None
         $Access=[System.Security.AccessControl.AccessControlType]::Allow
         $AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule("$userprincipalname",$Rights,$Inherit,$Propogation,$Access)
         $ACL = Get-Acl $userDir
         $ACL.AddAccessRule($AccessRule)
         $Account = new-object system.security.principal.ntaccount($userprincipalname)
         $ACL.setowner($Account)
         $ACL.SetAccessRule($AccessRule)
         Set-Acl $userDir $ACL
    }

Thank you very much for this tip Shay Levy!


BgPing – A High Performance Bulk Ping Utility


xb90 from Posh Tips has written a gorgeous masterpiece; BgPing.

Description from Posh Tips:
“BgPing.ps1 is a Background Ping Script capable of pinging enormous hosts lists in record time. You could call it a Bulk Ping Script, a Mass Ping Script, a Batch Ping Script or even a Mega Ping Script but the bottom line is: this baby will crank through a lot of IP addresses (or hostnames) very quickly.”


Create mailbox to all users in a CSV based on the 3+3 naming policy

# Create mailbox to all users in a CSV based on the 3+3 naming policy.
# This will also create the user in AD
$parentcontainer = "contoso.com/container"
$homedirectory = "\contoso.com\users\$username"
 
# Prompt the user for password
$password = Read-Host "Enter password" -AsSecureString
 
# The following has to be done to import with european characters
cat "c:\temp\users.csv" > c:\temp\listtemp.csv
 
# Loop through the list and 
# - replace european letters with o,a or e.
# - create username based on the 3+3 naming convention 
#   (three first letters in the firstname and lastname.)
# - all lower case
import-csv c:\temp\listtemp.csv | foreach {
    $username = ($_.firstname.substring(0,3) + $_.lastname.substring(0,3)).tolower()
    $username = $username.replace("ø","o")
    $username = $username.replace("å","a")
    $username = $username.replace("æ","e")
 
# The following line can create the user if you do not need mailbox.
#    new-qadUser -ParentContainer $parentcontainer -FirstName $_.firstname -LastName $_.lastname -DisplayName $($_.FirstName + " " + $_.LastName) -SamAccountName $username -Name $username -UserPrincipalName ($username + '@contoso.com') -whatif
 
# Create the mailbox
    New-Mailbox -Alias $username -Name $($_.FirstName + " " + $_.LastName) -OrganizationalUnit $parentcontainer -UserPrincipalName ($username + '@contoso.com') -SamAccountName $username -FirstName $_.firstname -LastName $_.lastname -ResetPasswordOnNextLogon $false -password $password -whatif
}

Adding snapins/modules to PowerShell

# Import the ActiveDirectory cmdlets
Import-Module ActiveDirectory
 
# List available snapins on your system:
Get-PSSnapin
 
# List registered snapins
Get-PSSnapin -Registered
 
# Alias:
gsnp
 
# Add Snapin:
Add-PSSnapin
 
# Examples:
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin # Exchange 2007
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 # Exchange 2010
Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager # WMM (Hyper-V)
Add-PSSnapin Quest.Activeroles.ADManagement # Quest commandlets

(You can download the Quest Commandlets from

# Add Exchange 2007 commandlets (if not added)
if(!(Get-PSSnapin | 
    Where-Object {$_.name -eq "Microsoft.Exchange.Management.PowerShell.Admin"})) {
      ADD-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
    }
 
# Add Exchange 2010 commandlets (if not added)
if(!(Get-PSSnapin | 
    Where-Object {$_.name -eq "Microsoft.Exchange.Management.PowerShell.E2010"})) {
      ADD-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
    }
 
# Add Virtual Machine Manager (Hyper-V) commandlets (if not added)
if(!(Get-PSSnapin | 
    Where-Object {$_.name -eq "Microsoft.SystemCenter.VirtualMachineManager"})) {
      ADD-PSSnapin Microsoft.SystemCenter.VirtualMachineManager
    }
 
# Add Quest commandlets (if not added)
if(!(Get-PSSnapin | 
    Where-Object {$_.name -eq "Quest.Activeroles.ADManagement"})) {
      ADD-PSSnapin Quest.Activeroles.ADManagement
    }

Head on over to http://blogs.technet.com/b/heyscriptingguy/archive/2010/10/16/learn-how-to-load-and-use-powershell-snap-ins.aspx to learn more about snapins.