Skip to content
Snippets Groups Projects
Forked from an inaccessible project.
count-ad-objects.ps1 2.99 KiB
# Parameters
param(
	[Parameter(Mandatory=$true)][string]$ComputerName,
	[switch]$DebugOutput,
	[string]$ADModuleSource,
	[string]$RootDriveLetter
)

function debug($msg) {
	if($DebugOutput) {
		write-output $msg
	}
}


# Access to TS variables
debug "Initializing access to TS variables..."
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment

$credsVar = "EngrIT_ADReadCreds"
$countVar = "EngrIT_ADObjectMatches"
$ouVar = "EngrIT_ADObjectOU"

debug "Getting creds from TS variable $credsVar..."
$user = 'not set'
$pass = 'not set'

# Get creds
$credsProtected = $tsenv.Value($credsVar)
debug $credsProtected
$credsSplit = $credsProtected.split(';')
debug $credsSplit
$user = $credsSplit[0]
debug $user
$pass = $credsSplit[1]
debug $pass
	
debug "Converting given password to SecureString..."
$secpass = ConvertTo-SecureString $pass -AsPlainText -Force

debug "Creating PSCredential object..."
$psCreds = New-Object -typename System.Management.Automation.PSCredential -argumentlist $user, $secpass

# Copy AD module files from wintools to correct locations
$dest = "${RootDriveLetter}:\windows"
robocopy /s /r:3 /w:5 $ADModuleSource $dest *.* 2>&1

# Import PowerShell AD module
debug "Importing AD PS module..."
import-module activedirectory -force 2>&1

$dc = "UDC03.ad.uillinois.edu"
debug "Using $dc for AD connection."

# Count existing AD objects with name = $ComputerName
# Currently this returns 0 if it's truly 0, OR if the command fails (e.g. bad credentials, bad connection, etc.)
# Need to find a way to separate those results and return -1 for the latter
# http://idanve.blogspot.com/2017/11/verify-computer-name-against-active.html
debug "Counting matching AD objects..."
$count = -1
$count = @(Get-ADComputer -filter 'name -like $ComputerName' -credential $psCreds -server $dc).count
debug "Found $count."

# Save the count to a TS variable
debug "Saving object count to TS variable $countVar..."
$tsenv.Value($countVar) = $count

$ouString = "No AD object named $ComputerName was found"

if($count -gt 0) {
	if($count -eq 1) {
		# Get OU
		# Note: this has undefined behavior if more than one match is found
		debug "Found >0 OU matches. Getting OU..."
		$ou = (Get-ADComputer -filter 'name -like $ComputerName' -credential $psCreds -server $dc).DistinguishedName
		debug "OU: $ou"
		
		# Make OU string more readable and save to a TS variable

		# Regex for finding only OU names
		$regex = "[OU]{2}=[\w- ]+"

		# Save to array
		$ous = ($ou | select-string -pattern $regex -allmatches).matches

		# Reverse order
		[array]::Reverse($ous)

		# Build readable string
		$ouString = ""
		foreach($item in $ous) {
			$thisOU = $item.value.replace("OU=","")
			if($thisOU -ne "Urbana") {
				if($thisOU -ne "Engineering") {
					$ouString += $thisOU + "/"
				}
			}
		}

		# Remove trailing "/"
		$ouString = $ouString.substring(0, $ouString.length - 1)
	}
	else {
		$ouString = "Found >1 OU matches!?"
		debug $ouString
	}
}

# Save the OU string to a TS variable
debug "Saving OU to TS variable $ouVar..."
$tsenv.Value($ouVar) = $ouString