Script to remove Machine from SCCM

This topic contains 12 replies, has 3 voices, and was last updated by  Graham Beer 2 years, 8 months ago.

  • Author
    Posts
  • #23887

    Graham Beer
    Participant

    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

  • #23890

    Will Anderson
    Keymaster

    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!

  • #23891

    Graham Beer
    Participant

    Great, thank you Will, much appreciated !

  • #23892

    Graham Beer
    Participant

    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

  • #23893

    Will Anderson
    Keymaster

    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.

  • #23894

    Graham Beer
    Participant

    Thanks Will. That looks really nice.

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

  • #23895

    Graham Beer
    Participant

    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.

  • #23896

    Will Anderson
    Keymaster

    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. 🙂

  • #23905

    Tim Pringle
    Participant

    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
    
    
  • #23908

    Will Anderson
    Keymaster

    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...

  • #23913

    Tim Pringle
    Participant

    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 🙂

  • #23915

    Will Anderson
    Keymaster

    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. 🙂

  • #24063

    Graham Beer
    Participant

    Thanks Tim, great stuff. Many thanks...again 🙂

You must be logged in to reply to this topic.