Script to remove Machine from SCCM

Hi,

i’ve written my first script, to remove a Computer from SCCM. What i have written is this the best and cleanest format ? Want to learn best practices as i’m learning powershell.

#Load InputBox
[void][system.reflection.assembly]::loadwithpartialname(‘Microsoft.VisualBasic’)

#Run GUI input
$Computername = [Microsoft.Visualbasic.interaction]::inputbox(‘Enter a computer name’,‘Computer?’)

#Set Location
Write-output “Setting Location…”
Set-Location AAC: | out-null

#Set Computer Variable
cls
Write-output “Checking $ComputerName in SCCM…”
(” “)

#Check to see if Machine is in SCCM
$InSCCM = [Boolean](Get-CMDevice -name $ComputerName)

If ($InSCCM -eq $True) {
Write-output “The $ComputerName was removed from SCCM” (Remove-CMDevice -DeviceName $ComputerName -whatif)
}
else
{ write-output “Computer is not in SCCM” }
(” “)

#Set Location back
Set-Location C: | out-null

Hey there Graham,

Welcome! And congrats to being another SCCM admin getting hip to PowerShell. It’s a great product to learn with!

A good script to be sure! A couple of things though.

You have the WhatIf parameter in your Remove-Device command. You might want to take that out. I’d recommend adding [cmdletbinding(SupportsShouldProcess=$true)] to the top of your script to be able to use the common parameters (including -WhatIf).

I would also move the Write-output “The $ComputerName was removed from SCCM” line to after the Remove-Device command execution. That way if there’s a failure of the Remove-CMDevice command, it errors out before you get the message saying it was successful. Even better, maybe have it run the Get-CMDevice command after the Remove-CMDevice to verify that it’s been removed, and then have your verification message.

It’s a great start! Keep at it!

Great, thank you Will, much appreciated !

This look better Will ?

function Remove-SCCMDevice {
[CmdletBinding(SupportsShouldProcess=$true)]

 Param()

}

#Load InputBox
[void][system.reflection.assembly]::loadwithpartialname(‘Microsoft.VisualBasic’)

#Run GUI input
$Computername = [Microsoft.Visualbasic.interaction]::inputbox(‘Enter a computer name’,‘Computer?’)

#Set Location
Write-output “Setting Location…”
Set-Location AAC: | out-null

#Set Computer Variable
cls
Write-output “Checking $ComputerName in SCCM…”
(” “)

#Check to see if Machine is in SCCM
$InSCCM = [Boolean](Get-CMDevice -name $ComputerName)

If ($InSCCM -eq $True) {
(Remove-CMDevice -DeviceName $ComputerName) | Write-output “The $ComputerName was removed from SCCM”
}
else
{ write-output “Computer is not in SCCM” }
(” “)

#Confirm machine is not in SCCM
If ($InSCCM -eq $True) {
write-output “** A problem has occured, please check **” }
else
{}
(” “)

#Set Location back
Set-Location C: | out-null

Hey there Graham. I’ve made a few changes to your script to give you an idea of how I’d flow it out. Disclaimer: I didn’t get a chance to actually test this, as I haven’t built out my CM environment in my Azure lab yet. But, hopefully you’ll get the idea of how I would lay it out.

function Remove-SCCMDevice {
[CmdletBinding(SupportsShouldProcess=$true)]

Param($Computername = [Microsoft.Visualbasic.interaction]::inputbox(‘Enter a computer name’,‘Computer?’))
[void][system.reflection.assembly]::loadwithpartialname(‘Microsoft.VisualBasic’)

#Set Location
Write-output “Setting Location………”
Set-Location AAC: | out-null

#Set Computer Variable
cls
Write-output “Checking $ComputerName in SCCM…”
(” “)

#Check to see if Machine is in SCCM
$InSCCM = [Boolean](Get-CMDevice -name $ComputerName)

If ($InSCCM -eq $True) {

Try{
    Remove-CMDevice -DeviceName $ComputerName
    }#EndTry

Catch [System.Exception]{
    $RmvError = $Error | Select-Object -First 1
    Write-Output "$Computername could not be removed from SCCM.  The error was $RmvError."
    }#EndCatch

}#EndIf
else
{ write-output “$Computername is not in SCCM” }
(” “)

#Confirm machine is not in SCCM
$RecheckCM = [Boolean](Get-CMDevice -name $ComputerName)

If ($Recheck -eq $false) {
write-output “$Computername was successfully removed from SCCM.” }
else
{Write-Output “$Computername still exists in SCCM.”}
(” “)

#Set Location back
Set-Location C: | out-null
}

As a point, unless you’re building the script out for someone who is going to just double-click and execute, I’d really shy away from using a dialogue box and stay in the shell. Then you can use parameters, and even feed an array of machines to remove using something like a CSV in the pipe.

Thanks Will. That looks really nice.

How does the catch work ? Good to see how it should be done, very useful. Thanks.

Also, when it runs it doesn’t do anything now and the function, Remove-SCCMDevice isn’t working. What do i need to do ? Thanks.

There’s a really good article here on using try, catch, finally in your scripts: http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/11/hey-scripting-guy-march-11-2010.aspx

Like I mentioned earlier, I didn’t get a chance to test it. I just threw it together to show you some of the logic I’d use. Let me see if I can throw an SCCM install on a VM this afternoon and flesh it out for you. :slight_smile:

I’m not such a big fan of the SCCM cmdlets. Not sure if they’ve changed it with R2, but it was the case that they would only run in a 32 bit PowerShell session. That put me off them straight away, and already had quite a lot of scripts I’d written from the previous version of SCCM which turned out to work fine. Also prefer the hands dirty use of the WMI classes.

Here’s something you could maybe try if you’re okay steering away from the provided CM cmdlets into the WMI.


function Remove-SCCMComputer
{
    [CmdletBinding()]
    
    Param
    (
        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string] $Computername

    )
    
    Process
    {
    
        $ErrorAction = 'Stop'
        $site = 'MySite'

        Try 
        {
            $Computer = [wmi] (Get-WmiObject -ComputerName $env:computername -Namespace "root\sms\site_$site" -Class sms_r_system -Filter "Name = `'$Computername`'").__PATH
        }
        Catch 
        {

        }

        If (!$Computer) 
        {
            Write-Verbose -Message "The computer $Computername does not exist"
            Break
        }

        Try 
        {
            $Computer.psbase.delete()
        }
        Catch 
        {
            Write-Verbose -Message "An error occurred whilst attempting to remove $Computername"
            Break
        }

        Try 
        {
            $Computer = [wmi] (Get-WmiObject -ComputerName $env:computername -Namespace "root\sms\site_$site" -Class sms_r_system -Filter "Name = `'$Computername`'").__PATH
        }
        Catch 
        {

        }
        If ($Computer) 
        {
            Write-Verbose -Message "An error occured whilst trying to remove $Computername"
        }
        Else 
        {
            Write-Verbose -Message "$Computername has been succesfully deleted"
        }
    }
}

#Sample use
PS C:\Windows\system32> Remove-SCCMComputer -Computername computer1 -Verbose
VERBOSE: computer1 has been succesfully deleted

PS C:\Windows\system32> Remove-SCCMComputer -Computername computer1 -Verbose
VERBOSE: The computer computer1 does not exist

Hey there Tim, thanks for that!

As far as the cmdlets go, they went through some pretty massive revisions in R2, and with each CU they’ve made some pretty good improvements. I’m still finding the occasional broken parameter though. Overall, they do a good job of getting the day to day done. I just keep submitting those connect requests…

I might go back to trying them out again soon, though I handed product ownership role for SCCM at my work over to another colleague a bit ago so i could concentrate more on PowerShell. Will always have fond memories of making the add on menu items for the console though. SCCM = Greek god level power, PS=Zeus level power, SCCM + PS = Ming the Merciless on steroids without having Flash Gordon to stop him level power.

Still got the Advanced DSC courses to go through, but pretty certain it will be something above Ming level :slight_smile:

Yeah. That’s part of the reason why I’m working so hard on building up my Azure skills. Give me a virtual lab environment that’s accessible anywhere that I can roll servers out based on the scenarios that I want to use them in. Technology is amaze. :slight_smile:

Thanks Tim, great stuff. Many thanks…again :slight_smile: