Deleting records from SCCM and Active Directory

Tagged: ,

This topic contains 12 replies, has 2 voices, and was last updated by Profile photo of Ryane Helder Ryane Helder 9 months, 2 weeks ago.

  • Author
    Posts
  • #35584
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    Hello, I am writing a script to achieve the above results, based on a collection I created in SCCM and using a WQL query to narrow it down to any systems that have not had a heartbeat in over 30 days. The part I have yet to figure out is how to easily add sections to remove records from SCCM...I have tried a few methods, to no avail yet. I am pasting my code below with areas that note "REMOVE FROM SCCM" where needed. Please advise if you have any suggestion on how to go about this using my existing code! Thank you.

     
    
    Import-Module ActiveDirectory
    
    #Create file for logging TPOS
    $logfile = "C:\temp\SCCMTPOSLog.txt"
    $adlogfile = "C:\temp\RemovedfromAD.txt"
    
    #Create variables for SCCM
    $SCCMServer = "computer.company.net"
    $siteCode = "P60"
    $CollectionName = 'ECO - TPOS Older than 30 Days' 
    
    Write-Host "Retrieving register names from SCCM..." 
    
    #Retrieve SCCM collection by name 
    $Collection = Get-wmiobject -ComputerName $SCCMServer -NameSpace "ROOT\SMS\site_$SiteCode" -Class SMS_Collection -Filter "Name = '$CollectionName'" 
    
    #Retrieve members of collection 
    $registerNames = (Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\site_$SiteCode" -Query "SELECT * FROM SMS_FullCollectionMembership WHERE CollectionID='$($Collection.CollectionID)' order by name").Name 
    
    #Iterate through each of the register names
    foreach ($registerName in $registerNames) {
    
        Write-Host "Processing $registerName"
    
        #Check if register has a corresponding record in Active Directory
        $tempVar = Get-ADComputer $registerName
                
            if ($tempVar -like "Get-ADComputer : Cannot find an object with identity" ) { 
          
                Write-Host "Computer object NOT FOUND for $registerName"
                #REMOVE FROM SCCM
    
                }
    
            else {
                                
                Write-Host "Computer object $registerName exists"
    
                #Ping register name to see if it is currently on the network
                if (Test-Connection -ComputerName $registerName -Quiet -count 1) {
    
                    Write-Host "$registerName is online"
                    Add-Content $logfile "$registerName"
    
                    }
    
                else {
    
                    Write-Host "$registerName is offline and will be removed from AD and SCCM"
                    Remove-ADComputer -Identity "$registerName" -Confirm:$false 
                    #REMOVE FROM SCCM
                    Add-Content $adlogfile "$registerName removed from Active Directory and SCCM"
    
                    }
    
            } #else {
    
    } #foreach ($registerName in $registerNames) {
    
    
    
  • #35586
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    NOTE: I will not have access to the Config Mgr cmdlets on the machine where I will be running this script.

  • #35596
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    To remove a device in SCCM via wmi you need to get the resource id and then remove it from SMS_R_System

    $t =(Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\site_$SiteCode" -Query "SELECT * FROMSMS_CombinedDeviceResources WHERE Name = '$registerName'").ResourceID
    Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\Site_$SiteCode" -class SMS_R_System -filter "ResourceID= '$t' "|Remove-WmiObject
    
  • #35597
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    Thank you Jonathan – I did see this as an option, but is that something I can simply add in the two places where I need it, within the loop and if/else statements?

    for example:

     
    
    
    [CmdletBinding()]
    param (
    	[Parameter(Mandatory = $true)]
    	[System.String]
    	$CommandLineFilePath
    )
    
    function Get-SCCMOldTPOS {
    	[CmdletBinding()]
    	param(
    		[Parameter(Mandatory=$true)]
    		[System.String]
    		$FilePath
    	)
    
            #Create file for logging TPOS
            $logfile = "C:\temp\SCCMTPOSLog.txt"
            $adlogfile = "C:\temp\RemovedfromAD.txt"
            $sccmlogfile = "C:\temp\RemovedfromSCCM.txt"
    
            #Create variables for SCCM
            $SCCMServer = "computer.company.net"
            $sitename = "P60"
    
            Write-Verbose "Retrieving register names from text file..."
    
    	    #Retrieve a list of TPOS registers from text file and set to $registerNames
            $registerNames = Get-Content $FilePath 
            
            Write-Verbose "Checking SCCM records against AD..."
    
            #Iterate through each of the register names
    	    foreach ($registerName in $registerNames) {
    
            Write-Verbose "Processing $registerName"
    
                #Check if register has a corresponding record in Active Directory
                $tempVar = Get-ADComputer $registerName
                
                    if ($tempVar -like "Get-ADComputer : Cannot find an object with identity" ) { 
          
                    Write-Host "Computer object NOT FOUND for $registerName"
                    $resID = (Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\site_$sitename" -Query "SELECT * FROMSMS_CombinedDeviceResources WHERE Name = '$registerName'").ResourceID 
                    Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\Site_$sitename" -class SMS_R_System -filter "ResourceID= '$resID' "|Remove-WmiObject
                    Add-Content $sccmlogfile "$registerName removed from SCCM"
    
                    }
    
                    else {
                                
                        Write-Host "Computer object $registerName exists"
    
                        #Ping register name to see if it is currently on the network
                        if (Test-Connection -ComputerName $registerName -Quiet -count 1) {
    
                        Write-Host "$registerName is online"
                        Add-Content $logfile "$registerName"
    
                        }
    
                            else {
    
                            Write-Host "$registerName is offline and will be removed from AD and SCCM"
                            Remove-ADComputer -Identity "$registerName" -Confirm:$false 
                            $resID = (Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\site_$sitename" -Query "SELECT * FROMSMS_CombinedDeviceResources WHERE Name = '$registerName'").ResourceID 
                            Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\Site_$sitename" -class SMS_R_System -filter "ResourceID= '$resID' "|Remove-WmiObject
                            Add-Content $adlogfile "$registerName removed from Active Directory and SCCM"
    
                            }
    
                    } #else {
    
        } #foreach ($registerName in $registerNames) {
    
    } #function Get-SCCMOldTPOS {
    
    Write-Verbose "Commands completed successfully"  
                 
    #Run the Get-SCCMOldTPOS function using the text file path that was passed to this script
    Get-SCCMOldTPOS -FilePath $CommandLineFilePath -Verbose
    
    
    
    
  • #35599
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    You can add it like that or you could create another function that does the delete that is called from your current code.

  • #35600
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    Thank you Jonathan – I am running into one other issue now:

    "Remove-WmiObject : Generic failure"

    Any ideas there?

    Thanks again, you are a great help. 🙂

  • #35602
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    My first though would be some type of user access or remoting error via WMI. When I run the command in my lab even with multiple deletes on the same resourceid the remove-wmiobject completes without the error.

  • #35603
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    That was my thought too – but then wouldn't my other WMI calls fail as well? Get-WMIObject, etc.

  • #35604
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    Well the other wmi calls are explicitly specifying the remote computer name and the remove is being passed a object containing it.

    Another option is to try this

    $resID = (Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\site_$sitename" -Query "SELECT * FROMSMS_CombinedDeviceResources WHERE Name = '$registerName'").ResourceID 
    $SCCMClient = Get-WmiObject -ComputerName $SCCMServer -Namespace  "ROOT\SMS\Site_$sitename" -class SMS_R_System -filter "ResourceID= '$resID' "
    $SCCMClient.Delete()
    
  • #35605
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    Good call! I will try this in the morning when I get back in. You are very kind and thank you for your help! 🙂

  • #35623
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    Using that method, I get a new error:

    Exception calling "Delete" with "0" argument(s): "Generic failure"

  • #35625
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    Check to be sure that the user running the script has the delete resource for collection assigned in sccm

  • #35628
    Profile photo of Ryane Helder
    Ryane Helder
    Participant

    You are a GENIUS. 🙂 Thank you!!! Everything works great now.

You must be logged in to reply to this topic.