Back in 2012, I wrote a number of blog posts that highlighted the efficacy of PowerShell and how it could be used to make your life as a sysadmin easier. This article builds on Windows PowerShell: Extracting Strings Using Regular Expressions, Windows PowerShell: Essential Admin Scripts (Part 1), and Windows PowerShell: Essential Admin Scripts (Part 2) by walking you through three PowerShell scripts that automate everyday sysadmin tasks.

Creating new Active Directory users

The idea behind this script is to eliminate the laborious task of manually creating new accounts in Active Directory using the ‘Add User Account’ wizard. This script uses the contents of a CSV file containing user account information to automatically create new accounts in Active Directory.

To construct this script, we need the following main elements:

  • A ForEach-Object loop to iterate through each attribute to add to the new account
  • A variable to store the UserPrincipleName
  • The New-ADUser cmdlet with the properties of the new account created using the attribute information found in the CSV file
  • The Add-ADGroupMember cmdlet to add the users to a group (optional)

The first part of the script imports the contents of the CSV and then pipes it to a ForEach-Object loop. The ForEach-Object loop is responsible for looping through each attribute found in the CSV to add to the new account.

The ‘-AccountPassword’ parameter is used to set a default account password for the account. The ‘-ChangePasswordAtLogon’ parameter is used to force the changing of the default password when the account logs on for the first time. The ‘-Enabled’ parameter sets the account to be enabled.

Finally, the “Add-ADGroupMember” cmdlet adds the users to a specified Active Directory group.

The screenshot below shows a sample CSV file containing the users that will be created in Active Directory.

The screenshot below shows a sample of a new user account created in Active Directory containing the attribute information defined in the CSV file.

Creating new Active Directory script:

#Read the contents of the UsersImport.csv file and loop through each attribute to add to the new account
Import-Csv “C:\Temp\BulkADUsers\UsersImport.csv” | ForEach-Object {
$UserPrincupleName = $_.SamAccountName + “@YOURCOMPANYDOMAIN.COM”

#Set a default password for the account
#Set the account to force a password change at next logon
#Set the account to be enabled

New-ADUser `
-DisplayName $_.”DisplayName” `
-Name $_.”Name” `
-GivenName $_.”GivenName” `
-Surname $_.”Surname” `
-SamAccountName $_.”samAccountName” `
-UserPrincipalName $UserPrincupleName `
-Office $_.”Office” `
-EmailAddress $_.”EmailAddress” `
-Description $_.”Description” `
-AccountPassword (ConvertTo-SecureString “MyPa$$w0rd123!” -AsPlainText -force) `
-ChangePasswordAtLogon $true `
-Enabled $true `

#Add these users to a specified group
Add-ADGroupMember “EuropeEmployees” $_.”SAMAccountName”;

}

Patch Checker

This script will check the patch installation status on a local or remote host. The concept is simple – it takes a list of computers and a list of patch IDs and runs through the Get-HotFix cmdlet, outputting the results to a text file. This is useful for when you need to quickly check if a particular set of hosts have a specific set of patches installed (e.g. during a ransomware outbreak).

To construct this script, we need the following main elements:

  • A variable to store a list of computers
  • A variable to store a list of patch IDs
  • A nested ForEach loop to iterate through each computer and patch ID
  • An If and ElseIf statement to perform a conditional action based on the result of the Get-HotFix cmdlet
  • A try-catch-finally block to catch any Access Denied exceptions and write them to a log file

The first part of the script reads a text file containing a list of computers (see screenshot below), checks if each computer is online and stores the list of online computers into a variable called $ComputerList. A variable called $PatchList is used to store the contents of a text file (see screenshot below) containing a list of patch IDs.

A nested ForEach loop is used to iterate through each computer and each patch ID and run the Get-HotFix cmdlet for each respective computer and patch ID in the list.

The $DateTimeNow variable is used to store the result of the Get-Date cmdlet (the current date/time) which we can call at different points later in the script.

An If statement is used to execute the Get-HotFix cmdlet and write the results to a text file called $Computer.txt (the computer name that the Get-HotFix cmdlet was being execute on) when it finds that the patch is installed. Similarly, an ElseIf statement is used to execute the Get-HotFix cmdlet and write to the same text file when it doesn’t find that the patch is installed.

All this is wrapped in a try-catch-finally block to allows us to catch any ‘UnauthorizedAccessException’ errors and log them to a file called “AccessDeniedLog.txt”, along with the computer name and current date/time.

The screenshots below show examples of the text files containing the results of the patch installation status on a particular machine, as well as the AccessDeniedLog text file that contains a list of computers where the command couldn’t be executed due insufficient privileges.

Patch checker script:

#Read ComputerList.txt, check if each host is online and store the list of online hosts in the $ComputerList variable
$ComputerList = Get-Content “C:\Temp\PatchCheck\ComputerList.txt” | Where {$_ -AND (Test-Connection $_ -Quiet -Count 1)}

#Read PatchList.txt and store the contents in the $PatchList variable
$PatchList = Get-Content “C:\Temp\PatchCheck\PatchList.txt”

try
{

#Create a loop to iterate through $ComputerList and repeat this portion of code for each computer in the list
foreach ($Computer in $ComputerList)
{

#Create a loop to iterate through $PatchList and repeat this portion of code for each patch in the list
foreach ($Patch in $PatchList)

{

#Create a $DateTimeNow variable to store the current date/time
$DateTimeNow = (Get-Date -format o)

#Run the get-HotFix cmdlet and check if the patch number within the patch list is installed on the computer. Output the results to a text file.
if (Get-HotFix -ComputerName $Computer | Where-Object {$Patch -Contains $_.HotfixID} -ErrorAction Stop)

{
$Results = “$DateTimeNow,” + ” $Patch,” + ” INSTALLED, ” + $Computer | Out-File “C:\Temp\PatchCheck\$Computer.txt” -Append
}

#Run the get-HotFix cmdlet and check if the patch number within the patch list is not installed on the computer. Output the results to a text file.
elseif (Get-HotFix -ComputerName $Computer | Where-Object {$Patch -NotContains $_.HotfixID} -ErrorAction Stop)

{
$Results = “$DateTimeNow,” + ” $Patch,” + ” NOT INSTALLED, ” + $Computer | Out-File “C:\Temp\PatchCheck\$Computer.txt” -Append
}

}

}

}

#Catch any UnauthorizedAccessException errors and log them to a text file along with the date/time and computer name.
catch [System.UnauthorizedAccessException]

{
“$DateTimeNow, ” + “$Computer, ” + $Error[0] | Out-File “C:\Temp\PatchCheck\AccessDeniedLog.txt” -Append
}

finally
{
}

Notes:

  • You will need to run the script with an account that has Admin access to each of the computers you wish to check.
  • You will need to set the ExecutionPolicy to Unrestricted to allow the script to be executed.

Temp Cleaner

This script will clean up the common temporary folder locations on a Windows machine. You will find this handy if you needed to regularly free up disk space, you are concerned with privacy, or you need to speed up the malware/Adware/PUP clean-up process on a particular machine.

To construct this script, the main element we need is an Array to store our temporary folder locations.

The first part of the script stops the “Windows Update” and “Background Intelligent Transfer Service” services. This is required for clearing the “C:\Windows\SoftwareDistribution\*” folder.

An Array called $TempLocations is used to store the temporary folder locations we want to remove files from.

The ‘Remove-Item’ cmdlet is used to remove files from each of the locations within the $TempLocations array. We set ‘-Force’ to force the removal of hidden or read-only files, ‘-Recurse’ to recursively go through folders below the specified location, and ‘-ErrorAction SilentlyContinue’ to silently continue if an error occurs during the deletion process.

The ‘Clear-RecycleBin’ cmdlet is used to empty the recycle bin. Finally, the “Windows Update” and “Background Intelligent Transfer Service” services are started again using the Start-Service cmdlet.

Temp cleaner script:

#Stop the “Windows Update” service
Stop-Service -Name “wuauserv” -Force

#Stop the “Background Intelligent Transfer Service”
Stop-Service -Name “BITS” -Force

#Create an array with a list of temp locations and store them in the $TempLocations variable
$TempLocations = @(“C:\Windows\Temp\*”, “%USERPROFILE%\AppData\Local\Temp\*”, “C:\Windows\Prefetch\*”, “C:\Windows\SoftwareDistribution\*”, “C:\Users\*\AppData\Local\Microsoft\Windows\INetCache\Low\IE\*”, “C:\Users\*\AppData\Local\Google\Chrome\User Data\Default\Cache\*”, “C:\Users\*\AppData\Local\Mozilla\Firefox\Profiles\*.default\cache2\entries\*”)

#Delete all files in each folder within $TempLocations and silently continue if there is an error
Remove-Item $TempLocations -Force -Recurse -ErrorAction SilentlyContinue

#Empty the Recycle Bin
Clear-RecycleBin -Force -ErrorAction SilentlyContinue

#Start the “Windows Update” service
Start-Service -Name “wuauserv”

#Start the “Background Intelligent Transfer Service”
Start-Service -Name “BITS”

Notes:

  • These are default locations. If you store temp files in a custom location, the correct path will have to be reflected in the Array.
  • You will need to run the script with Administrator privileges.
  • You will need to set your ExecutionPolicy to Unrestricted to allow the script to be executed.