It’s that time of year – for me, anyway – the time of year when all of our Domain Service Account(s) passwords expire, and for me that means changing dozens of scheduled task RunAs accounts.
Side note: We did a security overhaul last year when the zero-day Exchange vulnerability CVEs CVE-2021-26855, CVE-2021-26857, CVE-2021-26858 and CVE-2021-27065 became wide-spread. I finally convinced our IT Management to reset Admin accounts, remove dated accounts and enable MFA for all Sys Admins.
Consequences be damned, we did it and fixed the services configured to use service accounts 20 years ago, and the initial pains were worth it – I would recommend any organization do it ASAP (and this script will help).
Which brings me to this year, when dozens of service accounts are scheduled to expire and it’s time to go change numerous Scheduled Task RunAs accounts 1-by-1.
PowerShell to the rescue!
The following script takes care of all this time-consuming work for you.
It will 1) import a CSV from the current directory containing the username,passwords of the service accounts you are changing, 2) search all Domain Computers (based on your OU of choice), 3) find what scheduled tasks are configured to use any of the usernames in the CSV, 4) updated the password (and username) used by the Scheduled Task.
The script requires two configurable variables:
- The Domain OU Structure you wish to search
- The name of a CSV containing the updated Service Account Usernames and Passwords.
As a fail-safe, the script will display your configured variables and ask to confirm before execution, giving you the opportunity to open/edit the file directly from the PowerShell window to make changes.
$SearchOU = "OU=SQL,OU=Servers,DC=molloy,DC=rocks" # Where to search in Active Directory for servers which might be using Service Accounts
$CSVName = "ServiceAccounts.csv" # Name of the local CSV file to be imported.
# DO NOT EDIT BEYOND THIS LINE
$CSV = Import-CSV .\$CSVName
Echo `n
write-host "You are using CSV File " -f cyan -nonewline
write-host ".\$CSVName" -f red -nonewline
write-host " and searching Active Directory OU and sub-OUs " -f Cyan
Write-Host "'$SearchOU'" -f red -NoNewline
Write-Host " for Scheduled Task Service Accounts to update automatically." -f Cyan
Echo `n
Write-Host "Please verify all variables before proceeding!" -foregroundcolor red
$ans1 = Read-Host "Do you want to change the OU or check your variables before continuing? [Y/N]"
if ($ans1 -eq "Y"){
powershell_ise.exe .\UpdateAccounts.ps1}
elseif ($ans1 -eq "N"){
$ans2 = Read-Host "Confirm execution [Y/N]"
if ($ans2 -eq "N"){
Read-Host -Prompt "Invalid response or execution aborted."
exit}
elseif ($ans2 -eq "Y"){
# GO time.
$CSV = Import-CSV .\$CSVName
Import-Module ActiveDirectory
Get-ADComputer -Filter {(Enabled -eq $True)} -Searchbase $SearchOU | Select Name | ForEach {
$computerName = $_.Name
Write-Host "----"
Echo "Searching $computerName for Service Accounts"
Echo `n
Invoke-Command -ComputerName $Computername -ScriptBlock {
foreach ($user in $Using:CSV) {
$acct = $user.acct
$pass = $user.pass
foreach($a in $acct){
schtasks.exe /query /V /FO CSV | ConvertFrom-Csv | Select-Object TaskName,"Run As User" | Where-Object {$_."Run As User" -contains $a} | export-csv $env:TEMP\test.csv -NoTypeInformation
$tasks = Import-csv $env:TEMP\test.csv
$taskname = $tasks.TaskName -replace '^\\'
if ($TaskName) {
foreach ($c in $taskname) {
write-host "Scheduled Task Found: $C" -f Green
# write-host schtasks /change /tn $c /RU $acct /RP $Pass
schtasks /change /tn $c /RU $acct /RP $Pass
}
remove-item $env:TEMP\test.csv
Write-host "The following Service and Account Passwords have been changed on $Using:Computername" -f Green
write-host $c $acct
Echo `n
}
}
}
}}}}
Read-Host -Prompt "Process complete! Review the output and manually verify service states as necessary."
The result?
All Scheduled Tasks with a RunAs account listed in the CSV have had their passwords changed on all servers in the Domain OU configured (one here for testing).
Combined this with my Service RunAs script and I am good for another year!