WSUS Tidy – Powershell

I normally set the below script on a weekly schedule. If you haven’t run this for a long period of time. It may crash out, but you’ll find that the cleanups are going through and eventually it will complete.
The stats write to a log file.

$DateFormat = Get-Date -format yyyymmdd
$Logfile = "C:\Source\wsuslogs\$Dateformat.log"

# WSUS Cleanup
Invoke-WsusServerCleanup -CleanupObsoleteUpdates -CleanupUnneededContentFiles -CompressUpdates -DeclineExpiredUpdates -DeclineSupersededUpdates | Out-File $Logfile

Find Stale AD Computers

Active directory can often be neglected and orphaned computer objects can get out of control. The below script will query your domain (remember to provide your FQDN in the variable at the top) for computers that have not spoken on the domain for 90 days.

By default, Active directory looks to change computer object passwords every 30 days. If you have a large mobile workforce that may not be connecting into the network for a long period of time, you may way to extend this. I find that 90 days works well for us.

NOTE: Be careful when using this on environments that have clusters. SQL Clusters for example, have a AD joined computer object for the name of the cluster. This does not update its lastlogonstamp and therefore gets caught by this script.

import-module activedirectory  
$domain = "domain.local"  
$DaysInactive = 90  
$time = (Get-Date).Adddays(-($DaysInactive)) 
# Get all AD computers with lastLogonTimestamp less than our time 
Get-ADComputer -Filter {LastLogonTimeStamp -lt $time} -Properties LastLogonTimeStamp | 
# Output hostname and lastLogonTimestamp into CSV 
select-object Name,@{Name="Stamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}} | export-csv c:\source\OLD_Computer.csv -notypeinformation


Find unlinked GPO and remove via Powershell

Working on RAP as a service in the past few weeks I have worked with Microsoft to clean up Group Polices. Below are a few of the scripts that were used and their purpose.

Find Unlinked GPOs and export to a CSV:

Import-Module GroupPolicy
function IsNotLinked($xmldata){ 
    If ($xmldata.GPO.LinksTo -eq $null) { 
        Return $true 
    Return $false 
$unlinkedGPOs = @() 
Get-GPO -All | ForEach { $gpo = $_ ; $_ | Get-GPOReport -ReportType xml | ForEach { If(IsNotLinked([xml]$_)){$unlinkedGPOs += $gpo} }} 
If ($unlinkedGPOs.Count -eq 0) { 
    "No Unlinked GPO's Found" 
    $unlinkedGPOs | Select DisplayName,ID | export-csv c:\Source\output\unlinked.csv -NoTypeInformation

I like to export to a CSV to clarify exactly what I am removing. Now to remove:

Import-csv C:\Source\Output\unlinked.csv | ForEach-Object {Remove-GPO -guid $}