A bit of housekeeping – Powershell

I have been busy with using Powershell in these past few days.

I would like to share with you two of the scripts that I used lately. They were both used because of a password change that was made on a service account.

Now the thing about service accounts in Windows 2003 is, they are good, they need elevated privileges in some cases, and since the account is used for the specific purpose then you know that you have to change it once in a while and you know where. Problem is though unless you catch them all – and someone – somewhere  did not update the password somewhere, then you will start having issues with account lockouts.

First is to get all the services from all the computers in my OU, and change the password

$logfile = "c:\temp\results.log"
$serviceaccount = "svcmacct"
$password = ""

$serviceslist = Get\QADComputer -SearchRoot "OU=Public Servers,DC=maishsk,DC=local" -OsName window* -searchscope "subtree" -ErrorAction SilentlyContinue | ` 
ForEach-Object {
    (Get\WmiObject -Class Win32_Service -ComputerName $_.Name -ErrorAction  `
            SilentlyContinue | where {
                $_.'StartName' -like $serviceaccount
            }
    )
}

[System.Reflection.Assembly\]::LoadWithPartialName('system.serviceprocess')

ForEach ($line in $serviceslist) {
    Write-Host Processing $line.Systemname
    $service = Get\WmiObject win32_Service -ComputerName $line.Systemname -Filter "Name='$($line.Name)'"
    Write-host Stopping Service $line.Name
    (new-object System.ServiceProcess.ServiceController($($line.Name),$($line.Systemname))).Stop()
    (new-object System.ServiceProcess.ServiceController($($line.Name),$($line.Systemname))).WaitForStatus('Stopped',(new-timespan -seconds 90))

    if ($? -eq $true) {
        $service.Change($null ,$null ,$null ,$null ,$null ,$null , $serviceAccount, $password )
        Write-host Starting Service $line.Name
        (new-object System.ServiceProcess.ServiceController($($line.Name),$($line.Systemname))).Start()
        (new-object System.ServiceProcess.ServiceController($($line.Name),$($line.Systemname))).WaitForStatus('Running',(new-timespan -seconds 40))

        write-output $(get\date -DisplayHint time)` --` Service` $($line.Caption)` on` $($line.SystemName)` has` been` updated` and` restarted >> $logfile
    } else {
        write-output $(get\date -DisplayHint time)` --` Service` $($line.Caption)` on` $($line.SystemName)` update` failed >> $logfile
    }
}

Line 5 – get all the computers in the desired OU and get the services.

Line 22 – Here is a wait statement for the service to stop, otherwise this will cause issues with the rest of script. Please remember that the time span is there to ensure that if something goes wrong – then you script will continue, otherwise you will have to close the shell window - Ctrl+C will not work.

Line 28 – logs the results to a file including a time stamp.

Second script was to change the passwords for all the scheduled tasks using this same service account

$mycomps = Get-QADComputer -SearchRoot "maishsk.local/Public Servers" -SearchScope Subtree -SizeLimit 0 

$logfile = "c:\temp\tasklist.csv"
$results = "c:\temp\results.log"

$report = @()
$mycomps | ForEach-Object -ErrorAction SilentlyContinue {
   schtasks.exe /s $_.Name /query /v /fo csv >> $logfile 2>>c:\temp\errors.txt
}
$report = import-Csv $logfile

##Get all tasks that are run under a certain user
$svcaccount = Read-Host "Please Enter Service account Name (Domain\Username)"
$mytasks = ""
$mytasks = $report | Where-Object {($_."Run As User" -like $svcaccount) -and ($_."Next Run Time" -ne "Disabled")} | select Hostname, TaskName

#Remove unwanted Characters
$mytasks | ForEach-Object {
    $_.TaskName = ($_.TaskName).Trimstart("\")
}

##Change credentials for the task
foreach ($task in $mytasks) {
    schtasks.exe /change /S $($task.HostName) /TN "$($task.Taskname)" /RP $password >> $results 2>>c:\temp\errors.txt
}

Line 9 – schtasks.exe is the was I decided to go to get the info – I could not find anything else in Powershell that would extract the info.

Line 18-19 – the output came back with an extra “\” in the beginning – I used the Trimstart method to remove it.

Line 25 – This actually took a while to find the exact syntax that I was looking for.

If you have any comments or  improvements I would appreciate you input.