Script to delete decommissioned servers in SCOM

This is a modified version of Tim McFadden's script. This script will take a text file containing the FQDNs of agents which need to be removed from SCOM. Note this process is for when a server has been decommissioned but was never removed from SCOM. If you are instead trying to remove the agent from a server that's still running, you should use Uninstall-SCOMAgent. Otherwise, they'll show up again under Pending Management.

Example usage: .\thisscript.ps1 -MS localhost -path "C:\temp\decommServers.txt"

Example output:
GAC Version Location
--- ------- --------
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.EnterpriseManag...
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.EnterpriseManag...
File contains 3 server names
Connecting to management group
Getting agent managed computers
Checking for ladc.lapfe.com
- Matched ladc.lapfe.com
Checking for bogus.lapfe.com
Checking for laapp1.lapfe.com
- Matched laapp1.lapfe.com
Deleting agents
2 Agents deleted

 

 # Script to delete decommissioned servers (where uninstall is not possible)
# Laura.Park@microsoft.com
# May 2017
# Based off of https://www.scom2k7.com/how-to-delete-scom-2012-r2-managed-computers-using-powershell/

[CmdletBinding()] 
param (
    [Parameter(Mandatory=$True, 
    ValueFromPipeline=$True, 
    ValueFromPipelineByPropertyName=$True, 
    HelpMessage='What is the SCOM Management Server name?')] 
    [Alias("MS")] 
    [string[]]$MSserver,

    [Parameter(Mandatory=$True, 
    ValueFromPipeline=$True, 
    ValueFromPipelineByPropertyName=$True, 
    HelpMessage='Allows you to specify a text file containing agent FQDNs')] 
    [string[]]$Path
)

[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")

function New-Collection ( [type] $type ) 
{
    $typeAssemblyName = $type.AssemblyQualifiedName;
    $collection = new-object "System.Collections.ObjectModel.Collection``1[[$typeAssemblyName]]";
    return ,($collection);
}

$deleteList = get-content -Path $path

write-output "File contains $($deleteList.count) server names"

# Connect to management group
Write-output "Connecting to management group"

$ConnectionSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MSServer)
$admin = $ConnectionSetting.GetAdministration()


Write-output "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()

# Get list of agents to delete
foreach ($name in $deleteList) 
{
    Write-output "Checking for $name"
    foreach ($agent in $agentManagedComputers)
    {
        if ($deleteCollection -eq $null) 
        {
            $deleteCollection = new-collection $agent.GetType()
        }

        if (@($agent.PrincipalName -eq $name))
        {
            Write-output "- Matched $name"
            $deleteCollection.Add($agent)
            break
        }
    }
}

if ($deleteCollection.Count -gt 0) 
{
    Write-output "Deleting agents"
    $admin.DeleteAgentManagedComputers($deleteCollection)
    if($?){ Write-output "$($deleteCollection.count) Agents deleted" }
}