Monday, January 30, 2012

PowerShell: Get All Nested Members of an AD Group

A quick PowerShell script to get all nested members of a group. Enjoy.

##############################################################################

# Script Name: AD_Get_All_Nested_Members_Of_Group.ps1

# Version: 1.0

# Author: Dean Bunn

# Last Edited: 01/30/2012

# Description: Get All Nested Members of an AD Group

##############################################################################

#Function for Group Members Check

function checkMember([string]$objCN)

{

#Var for LDAP Path

$ldapPath = "LDAP://" + $objCN

#Retrieve AD Object

$adObj = [ADSI]$ldapPath

#Null Check on Class

if($adObj.Class)

{

#Switch Statement for Object Type

Switch($adObj.Class.ToString().ToLower())

{

#Group Objects

"group"

{

#Loop Through Group Members and Perform Recursive Member Check

foreach($member in $adObj.member)

{

#Check to See If Member Has Been Checked Already

if(!$htUniqueMembers.ContainsKey($member))

{

#Add Member to Unique HashTable

$htUniqueMembers.add($member,"1")

#Run checkMember on This Group Member

checkMember $member.ToString()

}

}

}#End of Group

#User Objects

"user"

{

#Check to See If Member Has Been Added to Unique Member. If Not Then Add

if(!$htUniqueMembers.ContainsKey($objCN))

{

$htUniqueMembers.add($objCN,"1")

}

}#End of User

#Add Other Classes Here If Necessary

}#End of Class Switch Statement

}#End Class Null Check

}#End of checkMember Function


#HashTable for All Unique Members

$htUniqueMembers = @{}


#Run checkMember on Top Group

checkMember "CN=STATS-ALL-MEMBERS,OU=DEPARTMENTS,DC=MYCOLLEGE,DC=EDU"


#Loop Through Each Unique Group Member

foreach($uCN in $htUniqueMembers.Keys)

{

Write-Host $uCN

}

Saturday, January 28, 2012

PowerShell: Remote PSSession Files Filling Up Drive

Thanks to colleague's help, I was finally able to figure out why available disk size on one of my utility servers was shrinking so fast. Basically, remote PSSessions in PowerShell cause the system to download any required modules from the remote system. Since one of my scheduled scripts creates a remote PowerShell session to one of my unit's Lync servers, it was downloading 4 MB of Lync PowerShell files every time it runs (which is every 15 minutes). By the end of the day, the drive had lost another 400 MBs of space.

The PSSession files are created in a folder with a random name and have these three different file extensions.

.ps1xml

.psd1 (windows PowerShell Data)

.psm1 (windows PowerShell Module)

So I added to another maintenance script this PowerShell one liner to remove files and folders that are older than three hours in my admin account temp directory.

Get-ChildItem "C:\Users\adminaccount\AppData\Local\Temp" -recurse | Where {$_.CreationTime -lt (Get-Date).AddHours(-3) } | Remove-Item -Force –Recurse

PowerShell: Delete Child Domain DNS Records Using DNSCMD

One of the departments on campus recently upgraded their systems (located in child domain) and requested that my unit clean up their old DNS records and the IPv6 records for systems they forgot to disable IPv6 on. So I sent them an Excel spreadsheet of their records and then sent me back which ones to delete. Then I created the script below to remove the 400+ records. Due to the way the DNSCMD command works, I had to add some serious variable checking and a five second delay between records so that it would work.

##############################################################################

# Script Name: DNS_Delete_Records_Listed_in_CSV.ps1

# Version: 1.0

# Author: Dean Bunn

# Last Edited: 01/27/2012

# Description: Deletes Child Domain DNS Entries from CSV File

##############################################################################

#Var for DNS Server

$dnsServer = "dc1.mycollege.edu"

#Var for DNS Zone

$dnsZone = "mycollege.edu"

#Var for Child Domain Name

$childDomain = "adax"

#Load CSV of Records to Be Deleted (Headers: Name, Type, and Data)

$dnsDeleteRecords = Import-Csv "c:\Users\adminaccount\Desktop\DNS_Delete.csv"

foreach($ddr in $dnsDeleteRecords)

{

#Var for Host Name

$hostName = $null

#Var for Record Type

$rType = $null

#Var for IP Address

$ipAddr = $null

#Check Length of Host Name Before Assigning Var

if($ddr.Name.ToString().Trim().Length -gt 1)

{

#Compose Hostname As SystemName.ChildDomain

$hostName = $ddr.Name.ToString().Trim() + "." + $childDomain.ToString()

}

#Switch Statement for Record Type

switch($ddr.Type.ToString().Trim())

{

"Host (A)"

{

$rType = "A"

}

"IPv6 Host (AAAA)"

{

$rType = "AAAA"

}

#Add Additional Record Types When Necessary

}

#Check the Length of the IP Address Information

if($ddr.Data.ToString().Trim().Length -gt 8)

{

#Assign IP Addr Var

$ipAddr = $ddr.Data.ToString().Trim()

}

if($rType -ne $null -and $hostName -ne $null -and $ipAddr -ne $null)

{

#Compose DNSCMD with Variables

#Should Look Like "dnscmd dc1.mycollege.edu /RecordDelete mycollege.edu dept-webstudent.adax A 192.168.60.49 `/f"

[string]$dnsDltCmd = "dnscmd $dnsServer /RecordDelete $dnsZone $hostName $rType $ipAddr `/f"

#Run the DNSCMD and Wait Five Seconds Before Moving to Next Entry

Invoke-Expression $dnsDltCmd

Start-Sleep -Seconds 5

}

else

{

Write-Host "Not Enough Info for " $ddr.Name

}

}#End of Foreach on $dnsDeleteRecords



Wednesday, January 4, 2012

PowerShell: Protect All AD Objects in Specific OUs

A strong need came up to set all AD objects in specific OUs with "Protect Object from Accidental Deletion"; however, some of these OUs were in different domains and this would require that would require a specific server setting for the Get-ADObject command. I solved this issue by using a hashtable to store the OU and DC info.

Enjoy.

##############################################################################

# Script Name: AD_Prevent_Accidental_Deletion.ps1

# Version: 1.5

# Author: Dean Bunn

# Last Edited: 01/01/2011

# Description: Protect All AD Objects in Select OUs from Accidental Deletion

##############################################################################

#Add Active Directory Module

Import-Module ActiveDirectory

#Create a HashTable to Hold OUs

$hOU = @{}

#Add OU and DC Info into HashTable

$hOU["ou=Payroll,dc=campus,dc=edu"] = "dccmp1.campus.edu"

$hOU["ou=Payroll,dc=campus,dc=edu"] = "dccmp1.campus.edu"

$hOU["ou=Marketing,dc=phys,dc=campus,dc=edu"] = "dcphys1.phys.campus.edu"

$hOU["ou=Marketing,dc=phys,dc=campus,dc=edu"] = "dcphys1.phys.campus.edu"

#Loop Through the OU HashTable

foreach($key in $hOU.keys)

{

#Assign OU and Server Names to Local Variables (Easier to Read Command)

$srchBase = $key.ToString()

$srvr = $hOU[$key].ToString()

#Set "Protect Object from Accidental Deletion" on All OU AD Objects

Get-ADObject -Filter * -SearchBase $srchBase -ResultPageSize 500 `

-SearchScope Subtree -Properties ProtectedFromAccidentalDeletion -Server $srvr `

| Where {$_.ProtectedFromAccidentalDeletion -eq $false} `

| Set-ADObject -ProtectedFromAccidentalDeletion $true -Server $srvr

}