Share via


SCOM 2012 Powershell command to remove agent

Question

Thursday, June 13, 2013 10:06 PM

Hello,

Has anyone had any luck removing agents via Powershell to mimic the delete agent from the console?

Blogs don't turn up anything useful for this task.

The 2012 Powershell covers how to approve agents, add proxy flag, and uninstall agent, but nothing to remove.  Used the SQL stored procedure previously in 2007R2 (and same procedure exists in 2012 SP1. 

Anyone aware of Powershell automate agent removal?

Thanks!

SCOM Power Shell to add SCOM 2012 agent
Get-SCOMPendingManagement | where {$_.AgentName -eq "ServernameFQDN"} | Approve-SCOMPendingManagement
Enable Proxy on newly added agent
Get-ScomAgent | where-object {$_.DisplayName -like "okcnmo*"} | where-object {$_.ProxyingEnabled.Value -eq $False} | Enable-SCOMAgentProxy

SQL Query to remove
http://social.technet.microsoft.com/Forums/en-US/operationsmanagergeneral/thread/e413c030-509b-45e4-bcd4-b4ae1a649c73
Uninstall Agent
http://technet.microsoft.com/library/hh545186.aspx
Remove Unix agents
http://social.technet.microsoft.com/Forums/en-US/operationsmanagerunixandlinux/thread/081f2801-7dfa-4db9-8c78-6adbc487a031/

All replies (17)

Thursday, May 9, 2019 6:11 PM ✅Answered | 1 vote

Your script worked well for me after a few minor modifications.  I am running this as a function from my desktop.  I added a get-credential so I could access the server remotely. I do a little user ID manipulation since our company requires we use a standard user ID on our PCs and only use admin creds when needed.  Be sure to replace the SCOMServer FQDN entry.

Function Remove-SCOMAgent
{

 [CmdletBinding()]
 Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [string]$AgentName
    )

$UserID = $Env:UserName
$Domain = $env:USERDOMAIN
$AdminID = $UserID + "-Admin"
$Cred = Get-Credential -Message "Enter Admin PW" -Username "$Domain\$AdminID"
    


#Import-Module OperationsManager            
New-SCOMManagementGroupConnection -ComputerName <SCOMSERVER.FQDN> -Credential $Cred
Start-Sleep -s 3

$administration = (Get-SCOMManagementGroup).GetAdministration();
Start-Sleep -Milliseconds 500
$agentManagedComputerType = [Microsoft.EnterpriseManagement.Administration.AgentManagedComputer];
$genericListType = [System.Collections.Generic.List``1]
$genericList = $genericListType.MakeGenericType($agentManagedComputerType)
$agentList = new-object $genericList.FullName
$agent = Get-SCOMAgent *$AgentName*
Start-Sleep -S 5
$agentList.Add($agent);

$genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1]
$genericReadOnlyCollection = $genericReadOnlyCollectionType.MakeGenericType($agentManagedComputerType)
$agentReadOnlyCollection = new-object $genericReadOnlyCollection.FullName @(,$agentList);    
$administration.DeleteAgentManagedComputers($agentReadOnlyCollection);
}

Friday, June 14, 2013 4:24 AM

Removing orphaned Operations Management, pls. refer to the following post
http://blogs.technet.com/b/momteam/archive/2012/02/21/removing-orphaned-operations-management-agents-using-powershell.aspx
http://support.microsoft.com/kb/2626752
Roger


Friday, June 14, 2013 4:27 AM

Hi,

You can use Uninstall-SCOMAgent command to remove scom agent.

refer below URL for more information

http://technet.microsoft.com/library/hh545186.aspx

for delete refer below link

http://blogs.msdn.com/b/scshell/archive/2007/04/25/deleting-agents.aspx

Regards

sridhar v


Friday, June 14, 2013 6:52 AM

Hi,

Please see if the following method helps:

QuickTricks: How to bulk uninstall agents in OpsMgr 2012 by name in PowerShell (#SCOM, #PowerShell, #SYSCTR)
http://blogs.catapultsystems.com/cfuller/archive/2012/06/21/quicktricks-how-to-bulk-uninstall-agents-in-opsmgr-2012-by-name-in-powershell-scom-powershell-sysctr.aspx

Thanks.

Nicholas Li
TechNet Community Support


Friday, June 14, 2013 9:51 AM

I'm not really sure of what you're trying to achieve, but uninstalling an agent using powershell is rather easy and well documented :

Get-SCOMAgent "dnshostname.ofagent.com" | Uninstall-SCOMAgent -ActionAccount (Get-Credential)


Friday, June 14, 2013 4:08 PM | 1 vote

Gents,
Thank you Sridhar, but the 2007 Powershell commandlet isn't available in 2012 (Delete-Agent).
Thank you CyrAz and Nicholas for Uninstall syntax, already aware.

Let me try again, removing an agent from SCOM console is NOT uninstalling an agent.

Reproducing via PowerShell to delete agent from SCOM console:
Click on Administration Tab, Agent Managed, and right clicking Agent, choosing Delete (removes the agent from SCOM)

As stated in the delete agent blog Sridhar quoted, Uninstall agent doesn't cover all scenarios.

  • Agent/server is down
  • SCOM Administrator does NOT have admin on removed machine
  • SCOM Local System Action/Windows Account does not work, only administrator level access specified in PowerShell works

Nothing I have come across nor the responses indicate how to delete an agent via Powershell without going to SQL backend.

NOTE: SCOM console calls stored procedure to remove the agent.

Anyone aware how in PowerShell to mimic SCOM Console agent delete when Uninstall-Agent fails based on scenarios above without going to backend SQL script?

Thanks


Sunday, June 16, 2013 6:14 PM

One thing, if you do have the scom snapping from 2007r2 you can still import it and use the old cmdlets.  I'm trying to figure out a way to do it using the new cmdlets and I'll get back to you when I find something.  That's a pretty big missing cmdlet, I'm glad you brought it up. 

Hope that helps! Jason


Monday, December 23, 2013 12:25 PM | 5 votes

Hi,

I got this fixed today. I modified Roger Sprague's script(http://blogs.msdn.com/b/scshell/archive/2007/04/25/deleting-agents.aspx) to a 2012 usable version:

Import-Module OperationsManager            
New-SCOMManagementGroupConnection -ComputerName %SCOM_MGMT Server%
$Servername = "%AgentName%"$administration = (Get-SCOMManagementGroup).GetAdministration();
$agentManagedComputerType = [Microsoft.EnterpriseManagement.Administration.AgentManagedComputer];
$genericListType = [System.Collections.Generic.List``1]
$genericList = $genericListType.MakeGenericType($agentManagedComputerType)
$agentList = new-object $genericList.FullName$agent = Get-SCOMAgent *$Servername*$agentList.Add($agent);

$genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1]
$genericReadOnlyCollection = $genericReadOnlyCollectionType.MakeGenericType($agentManagedComputerType)
$agentReadOnlyCollection = new-object $genericReadOnlyCollection.FullName @(,$agentList);    
$administration.DeleteAgentManagedComputers($agentReadOnlyCollection);

Best Regards

Thomas


Thursday, January 2, 2014 3:41 PM

Thomas,

Thank you very much for posting this!


Thursday, February 27, 2014 4:49 PM

We actually have used the stored procedure for 2007 and 2012

OperationsManager.dbo.p_TypedManagedEntityDelete

If you want to use Invoke-Sqlcmd to run the query.

Another way from SQL which can be put in PowerShell

 

--Grab GUID for that health service

select * from BaseManagedEntity

where FullName like '%<servername>%'

and IsDeleted = 1

 

Look for FullName with Microsoft.SystemCenter.HealthService:servername

-- Use this to test the entity delete for the healthservice GUID

 

DECLARE @EntityId uniqueidentifier;

DECLARE @TimeGenerated datetime;

 

-- change "GUID" to the ID of the invalid entity

SET @EntityId = '<GUID here>';

SET @TimeGenerated = getutcdate();

 

BEGIN TRANSACTION

 

EXEC dbo.p_TypedManagedEntityDelete @EntityId, @TimeGenerated;

 

COMMIT TRANSACTION

 

--Check what is in deleted

select * from BaseManagedEntity

where IsDeleted = 1


Tuesday, May 20, 2014 10:37 PM

Thomas,

TYVM for the code above, wanted to let other folks know it works on SCOM 2012 exactly as described, and gladly not have to mess with SCOM db directly.

tip: if you tried to script delete agents that are NOT orphaned, you end up with ghost agent entries that do not work, and you cant delete via the gui/script, they will go away for about a min and come back on the admin console.  Have not found a solution to this yet, but more than happy to not have to do agent cleanup via gui one by one anymore.

Jack


Thursday, August 21, 2014 5:38 PM

Thomas,

Been combing the web for days looking for exactly this.

Thanks a bunch

+10pts to you!


Monday, June 1, 2015 7:21 PM

Hello

What's this (''1)? It's not working for me.

$genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1]


Monday, June 1, 2015 8:50 PM | 1 vote

Max,

I am not sure if Thomas will respond to your question about his code.

The stored procedure worked pretty good, but missed some objects like clustered servers and all their virtual aliases.

Try this...

############################################################################
# Script:  ScomAgentDeleteSDK.ps1 
# this script will delete agents using the SDK binaries and .NET based SDK commands
# Takes a single parameter of a computer FQDN
############################################################################

############################################################################
# Function Get-SDKServername is only needed if you want to make 
# this script portable to any machine that has the SCOM Console installed
# You can choose to hard code this or use the function
############################################################################
function Get-SDKServerName
{
    # Get SDK server name
    # Lifted from Microsoft.EnterpriseManagement.OperationsManager.CleintShell.Functions.ps1
    $UserRegKeyPath = "HKCU:\software\Microsoft\Microsoft Operations Manager\3.0\User Settings";
    $MachineRegKeyPath = "HKLM:\software\Microsoft\Microsoft Operations Manager\3.0\Machine Settings";
    $UserRegValueName = "SDKServiceMachine";
    $MachineRegValueName = "DefaultSDKServiceMachine";
    $regValue = $null;
    $server = $null;

    $regValue = Get-ItemProperty -path:$UserRegKeyPath -name:$UserRegValueName -ErrorAction:SilentlyContinue;

    if ($regValue -ne $null)
    {
        $server = $regValue.SDKServiceMachine;
    }

    if ($server -eq $null -or $server.Length -eq 0)
    {
        $regValue = Get-ItemProperty -path:$MachineRegKeyPath -name:$MachineRegValueName -ErrorAction:SilentlyContinue;
     
        if ($regValue -ne $null)
        {
            $server = $regValue.DefaultSDKServiceMachine;
        }
    }

    if ($server -eq $null) 
    {
        $server = "localhost"
    }

    return $server
}

############################################################################
# Function Get-InstallDirectory is used to find the installation path  
# of SCOM in order to located the SDK binaries which need to be loaded
############################################################################
function Get-InstallDirectory
{
    # Get Install directory
    $SetupRegKeyPath = "HKLM:\software\Microsoft\Microsoft Operations Manager\3.0\Setup";
    $InstallDirRegValueName = "InstallDirectory";

    $InstallDir = "$env:SystemDrive\Program Files\System Center Operations Manager 3.0";

    $regvalue = $null;
    $regValue = Get-ItemProperty -path:$SetupRegKeyPath -name:$InstallDirRegValueName -ErrorAction:SilentlyContinue;
    if ($regvalue -ne $null) 
    {
        $InstallDir = $regValue.InstallDirectory;
    }

    return $InstallDir
}


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

############################################################################
# Log output file name per server when script called
# Uncomment this for logging purposes
############################################################################


# Load SDK dlls
$server = Get-SDKServerName
$InstallDir = Get-InstallDirectory
$sdkDir = "$InstallDir\SDK Binaries"
echo "Loading SDK"
$dummy = [System.Reflection.Assembly]::LoadFrom("$sdkDir\Microsoft.EnterpriseManagement.Core.dll")
$dummy = [System.Reflection.Assembly]::LoadFrom("$sdkDir\Microsoft.EnterpriseManagement.OperationsManager.dll")
$dummy = [System.Reflection.Assembly]::LoadFrom("$sdkDir\Microsoft.EnterpriseManagement.Runtime.dll")

# Connect to management group
echo "Connecting to management group"
$managementGroup = [Microsoft.EnterpriseManagement.ManagementGroup]::Connect($server)
$admin = $managementGroup.GetAdministration()

echo "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()

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

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

if ($deleteCollection.Count -gt 0) 
{
    echo "Deleting agents"
    $admin.DeleteAgentManagedComputers($deleteCollection)
    if($?){ echo "Agents deleted" }
}
else
{
    echo "No Match for $name"
    Write-Host -ForegroundColor Yellow "NO agent $name found, manual intervention required"
}

Friday, December 11, 2015 6:36 AM

Hi,

I created PowerShell Module. It also includes CmdLet »Remove-JLabSCOMAgentManaged«  to remove Agent(s) from SCOM. Part of kjustin1996 script is incorporated in this CmdLet so credits also go to him.

For more info visit: https://jurelab.wordpress.com/2015/12/10/operations-manager-2012-r2-custom-powershell-module/

Hope it helps

Jure

Jure Labrovic | Blog


Monday, April 24, 2017 4:06 PM

I've created a script that uses both the delete method and the uninstall-scomagent. I've yet to test how it handles maintenance mode agents, but so far the results are better than just run the "delete" for all.

(based on this script)



Param( [Parameter(Mandatory=$True,Position=1)][string]$ServerName,
       [Parameter(Mandatory=$True,Position=1)][string]$SCOMManagementServer
     )

if (!(Get-Module -ListAvailable -Name Operationsmanager)) {
    Import-Module Operationsmanager
}
else {write-host "opsmgr already loaded"}


function DeleteSCOMAgent{
#This function deletes the scomagent when the managed computer doesn't exist anymore
    Param(
      [string]$ManagementServer,
      [string]$AgentFQDN
    )

    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager.Common") 
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager")


    #SCOM Management Group Connection
    $MGConnSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroupConnectionSettings($ManagementServer) 
    $MG = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MGConnSetting) 
    $Admin = $MG.Administration

    $agentManagedComputerType = [Microsoft.EnterpriseManagement.Administration.AgentManagedComputer]; 
    $genericListType = [System.Collections.Generic.List``1] 
    $genericList = $genericListType.MakeGenericType($agentManagedComputerType) 
    $agentList = new-object $genericList.FullName

    #Replace DNSHostName with FQDN of agent to be deleted. 
    #ComputerName is a SCOM management server to query 
    $agent = Get-SCOMAgent -DNSHostName $AgentFQDN -ComputerName $ManagementServer 
    $agentList.Add($agent);

    $genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1] 
    $genericReadOnlyCollection = $genericReadOnlyCollectionType.MakeGenericType($agentManagedComputerType) 
    $agentReadOnlyCollection = new-object $genericReadOnlyCollection.FullName @(,$agentList);

    #Remove objects
    $admin.DeleteAgentManagedComputers($agentList)
    $MG.EntityObjects.DeleteDisabledObjects()
}




try {
    Write-Host "Adding SCOMManagementGroupConnection for server [$PrimaryMgmtServerName]"
    $conn = New-SCOMManagementGroupConnection $SCOMManagementServer -PassThru

    # See if there already is an agent instance in SCOM
    Write-Host "Checking for possible existence of a SCOM agent"
    $SCOMAgent = Get-SCOMAgent -DNSHostName $ServerName
    $class = get-scomclass -DisplayName "health service watcher (agent)"
    $scomagentHW = Get-SCOMClassInstance -Class $class|where-object {$_.DisplayName -eq $ServerName}

    if (!$scomagentHW){
        Write-Host "No agent found. uninstallation not necessary"
    }
    else {
        if ($scomagentHW.healthstate -eq "Success") {
            Write-Host "SCOM Agent found and alive. Starting uninstall of the SCOM Agent"
            Uninstall-SCOMAgent -Agent $SCOMAgent
        }
        else {
            Write-Host "SCOM Agent found but not healthy. Deleting the SCOM Agent"
            DeleteSCOMAgent -ManagementServer $PrimaryMgmtServerName -AgentFQDN $ServerName
        }
    }
}
catch {
    # Rethrow exception
    throw $_.Exception.Message
}
finally
{
    Remove-SCOMManagementGroupConnection $conn
}

Write-Host "Finished uninstallation of the agent."

Rob Korving
http://jama00.wordpress.com/


Monday, August 5, 2019 4:50 AM

Hi ,

thanks alot for the helpfull info, just adding some lines to read a text file to delete bulk agents:

Function Remove-SCOMAgent
{
         
$AgentName = get-content -Path C:\Temp\AgentName.txt
$UserID = $Env:UserName
$Domain = $env:USERDOMAIN
$AdminID = $UserID 
$Cred = Get-Credential -Message "Enter Admin PW" -Username "$Domain\AdminID"

#Import-Module OperationsManager            
New-SCOMManagementGroupConnection -ComputerName "(yournamagementserver)" -Credential $Cred
Start-Sleep -s 3
foreach ($AgentNames in $AgentName) {
$administration = (Get-SCOMManagementGroup).GetAdministration();
Start-Sleep -Milliseconds 500
$agentManagedComputerType = [Microsoft.EnterpriseManagement.Administration.AgentManagedComputer];
$genericListType = [System.Collections.Generic.List``1]
$genericList = $genericListType.MakeGenericType($agentManagedComputerType)
$agentList = new-object $genericList.FullName
$agent = Get-SCOMAgent *$AgentNames*
Start-Sleep -S 5
$agentList.Add($agent);

$genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1]
$genericReadOnlyCollection = $genericReadOnlyCollectionType.MakeGenericType($agentManagedComputerType)
$agentReadOnlyCollection = new-object $genericReadOnlyCollection.FullName @(,$agentList);    
$administration.DeleteAgentManagedComputers($agentReadOnlyCollection);
    }
}

All credits to MarkDMac