Deletes any target group that has no computers associated with it. This script contributed by the Microsoft Windows Server Update Services (WSUS) team.

This script connects to a WSUS 3.0 server on the machine where the script runs. This script can be adapted to connect to remote WSUS 3.0 servers by changing the GetUpdateServer() call to GetUpdateServer(<servername>, true|false), where <servername> is the name of the remote WSUS server, and true|false refers to the use of SSL to make the connection.

[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer();

function ProcessGroup {

    #depth first, so you delete the deepest group first
    $childCount = 0;

    $parentGroup.GetChildTargetGroups() | foreach-object {
        $processCount = ProcessGroup($_);
        $childCount = $childCount + $processCount;

    $count = 0;

    $count = $parentGroup.GetComputerTargets($false).Count;

    $totalCount = $count + $childCount;

    if ($totalCount -eq 0) {
        if ($parentGroup.Id -eq [Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::AllComputers) { }
        elseif ($parentGroup.Id -eq [Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::UnassignedComputers) { }
        elseif ($parentGroup.Id -eq [Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::WindowsProductIdValidated) {}
        else {
            "Delete "+$parentGroup.Name | out-host;

    return $totalCount;

$AllComputersGroup = $wsus.GetComputerTargetGroup([Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::AllComputers);
ProcessGroup($AllComputersGroup) | out-null;