none
Remove direct computer association from collection by script RRS feed

  • Question

  • Currently i have a OSD task sequence that is advertised to a specific collection. The aim of this task sequence reimages machines that are currently on the network, that for some reason or another has a problem which is easier solved by reimaging.

    At the moment i simply create a direct computer association in the collection and then the machine receives the job and it all works fine.

    I'd like to be able to remove the direct computer association from this collection after the job has finished automatically. Is this possible by adding in an additional task sequence to run a script?
    Matt Summer
    Friday, February 27, 2009 12:51 PM

Answers

  • I re-written the script above (excellent Ruben!) so it will work when executed by a Status filter rule.

    Create a Status Filter rule that will trigger on:
    Component : Task Sequence Manager
    Message ID: 11171 

    On the next page:
    save the script below on the sccm server and trigger the below script with something like:

    cscript.exe E:\SCCMtools\remove.vbs %msgsys


    This will trigger the script each time a Task sequence is reported to the SCCM primary site to be completed successfully and will use the computername from the status message and remove it from the collection in the script(you need to change it).

    No service account needed as it runs under System account.

    On Error Resume Next  
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection  
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet  
     
    Set oNetwork = CreateObject(”WScript.NetWork”)   

    ‘CollectionID from which to remove the comouter

    sCollectionID = “0010004A” 

    ‘————————————————————
    ‘Get Command Line arguments

    Set args = WScript.Arguments
    sComputername = args.Item(0)
    If sComputerName = NULL then
       wscript.quit
    End if

    ‘————————————————————
    ‘Main script

        Set swbemLocator = CreateObject(”WbemScripting.SWbemLocator”)
        swbemLocator.Security_.AuthenticationLevel = 6 ‘Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(”.”, “root\SMS”)
        Set oProviderLocation = swbemServices.InstancesOf(”SMS_ProviderLocation”)
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, “root\sms\site_” + oLocation.SiteCode)
            End If       
        Next

    Set oCollection = SWbemServices.Get(”SMS_Collection=’” & sCollectionID & “‘”)  
     
    RuleSet = oCollection.CollectionRules  
     
    For Each Rule In RuleSet  
        If Rule.Path_.Class = “SMS_CollectionRuleDirect” Then  
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then  
                oCollection.DeleteMembershipRule Rule  
            End If  
        End If  
    Next  
     
    WScript.Quit(0)

    Wednesday, March 10, 2010 10:04 PM
    Moderator
  • Very small adjustment:

    Usage:
    cscript.exe E:\SCCMtools\remove.vbs /ComputerName:%msgsys /ID:0010004A

    Advantage is that you can use this vbs to handle all collections you want.

    On Error Resume Next  
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection  
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet  
     
    Set oNetwork = CreateObject(”WScript.NetWork”)   
    Set oArguments = Wscript.Arguments
    
    ‘CollectionID from which to remove the comouter
    sCollectionID = objArguments.Named.Item("ID")
    sComputername = objArguments.Named.Item("ComputerName")
    
    ‘————————————————————
    ‘Get Command Line arguments
    
    If sComputerName = NULL then 
       wscript.quit
    End if
    
    ‘————————————————————
    ‘Main script
    
        Set swbemLocator = CreateObject(”WbemScripting.SWbemLocator”)
        swbemLocator.Security_.AuthenticationLevel = 6 ‘Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(”.”, “root\SMS”)
        Set oProviderLocation = swbemServices.InstancesOf(”SMS_ProviderLocation”)
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, “root\sms\site_” + oLocation.SiteCode)
            End If       
        Next
    
    Set oCollection = SWbemServices.Get(”SMS_Collection=’” & sCollectionID & “‘”)  
     
    RuleSet = oCollection.CollectionRules  
     
    For Each Rule In RuleSet  
        If Rule.Path_.Class = “SMS_CollectionRuleDirect” Then  
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then  
                oCollection.DeleteMembershipRule Rule  
            End If  
        End If  
    Next  
     
    WScript.Quit(0)

    Thursday, March 11, 2010 8:22 PM

All replies

  • Hi,

    If someone know the issue on Matthew's question, i am also interessed !

    I think we can use the dynamic collection and find the attribut that check the success installation OS and then remove the direct computer association in the collection.

    Someone got an idea about this attribut ?

    Thx
    Steph
    Monday, March 2, 2009 7:01 PM
  • You could add a step at the very end of the task sequence running a vb-script that removes the resource from the collection, something like the following:

    On Error Resume Next  
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection  
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet  
     
    Set oNetwork = CreateObject("WScript.NetWork")   
     
    sComputerName = oNetwork.ComputerName  
    sSMSServer = "SCCM" 
    sSMSSiteCode = "CEN" 
    sCollectionID = "CEN00001" 
    sUserName = "Domain\Username" 
    sUserPassword = "Password" 
     
    Set oLocator = CreateObject("WbemScripting.SWbemLocator")  
    oLocator.Security_.AuthenticationLevel = 6 
    Set oSWbemServices = oLocator.ConnectServer(sSMSServer, "root\sms\site_" & sSMSSiteCode, sUserName, sUserPassword)  
    Set oCollection = oSWbemServices.Get("SMS_Collection='" & sCollectionID & "'")  
     
    RuleSet = oCollection.CollectionRules  
     
    For Each Rule In RuleSet  
        If Rule.Path_.Class = "SMS_CollectionRuleDirect" Then  
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then  
                oCollection.DeleteMembershipRule Rule  
            End If  
        End If  
    Next  
     
    WScript.Quit(0) 

    Just make sure the user you use has the apropriate rights in SCCM (rights on collection + connect rights), you probably should make it a service account that can't log on and strip it of every other right it doesn't need as the password is clear text and somone could possibly snatch it.
    Friday, March 6, 2009 8:12 AM
  • Is there anyway to give the computer permissions to delete its own record in the collection then you could put the script in the startup script?

    Louis
    Monday, February 22, 2010 1:44 PM
  • Another way would be to create a status filter rule to trigger the script on the sccm server when the task sequence is finished, then you can run it as System.

    That should work perfectly, have a look at the status message in the site and sort out which message to trigger the script on.

    /Jörgen

    Thursday, March 4, 2010 8:48 PM
    Moderator
  • Do you have an example of how to do that, as I would also be intrerested in this, but can find an example elsewhere?


    Cheers
    James
    Wednesday, March 10, 2010 10:22 AM
  • http://technet.microsoft.com/en-us/library/cc181208.aspx

    My recommendation (not sure if it is applicable to your environment) is to have generic script that will search all collections and remove all direct memberships.

    Martin
    Wednesday, March 10, 2010 10:43 AM
  • I re-written the script above (excellent Ruben!) so it will work when executed by a Status filter rule.

    Create a Status Filter rule that will trigger on:
    Component : Task Sequence Manager
    Message ID: 11171 

    On the next page:
    save the script below on the sccm server and trigger the below script with something like:

    cscript.exe E:\SCCMtools\remove.vbs %msgsys


    This will trigger the script each time a Task sequence is reported to the SCCM primary site to be completed successfully and will use the computername from the status message and remove it from the collection in the script(you need to change it).

    No service account needed as it runs under System account.

    On Error Resume Next  
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection  
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet  
     
    Set oNetwork = CreateObject(”WScript.NetWork”)   

    ‘CollectionID from which to remove the comouter

    sCollectionID = “0010004A” 

    ‘————————————————————
    ‘Get Command Line arguments

    Set args = WScript.Arguments
    sComputername = args.Item(0)
    If sComputerName = NULL then
       wscript.quit
    End if

    ‘————————————————————
    ‘Main script

        Set swbemLocator = CreateObject(”WbemScripting.SWbemLocator”)
        swbemLocator.Security_.AuthenticationLevel = 6 ‘Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(”.”, “root\SMS”)
        Set oProviderLocation = swbemServices.InstancesOf(”SMS_ProviderLocation”)
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, “root\sms\site_” + oLocation.SiteCode)
            End If       
        Next

    Set oCollection = SWbemServices.Get(”SMS_Collection=’” & sCollectionID & “‘”)  
     
    RuleSet = oCollection.CollectionRules  
     
    For Each Rule In RuleSet  
        If Rule.Path_.Class = “SMS_CollectionRuleDirect” Then  
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then  
                oCollection.DeleteMembershipRule Rule  
            End If  
        End If  
    Next  
     
    WScript.Quit(0)

    Wednesday, March 10, 2010 10:04 PM
    Moderator
  • Very small adjustment:

    Usage:
    cscript.exe E:\SCCMtools\remove.vbs /ComputerName:%msgsys /ID:0010004A

    Advantage is that you can use this vbs to handle all collections you want.

    On Error Resume Next  
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection  
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet  
     
    Set oNetwork = CreateObject(”WScript.NetWork”)   
    Set oArguments = Wscript.Arguments
    
    ‘CollectionID from which to remove the comouter
    sCollectionID = objArguments.Named.Item("ID")
    sComputername = objArguments.Named.Item("ComputerName")
    
    ‘————————————————————
    ‘Get Command Line arguments
    
    If sComputerName = NULL then 
       wscript.quit
    End if
    
    ‘————————————————————
    ‘Main script
    
        Set swbemLocator = CreateObject(”WbemScripting.SWbemLocator”)
        swbemLocator.Security_.AuthenticationLevel = 6 ‘Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(”.”, “root\SMS”)
        Set oProviderLocation = swbemServices.InstancesOf(”SMS_ProviderLocation”)
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, “root\sms\site_” + oLocation.SiteCode)
            End If       
        Next
    
    Set oCollection = SWbemServices.Get(”SMS_Collection=’” & sCollectionID & “‘”)  
     
    RuleSet = oCollection.CollectionRules  
     
    For Each Rule In RuleSet  
        If Rule.Path_.Class = “SMS_CollectionRuleDirect” Then  
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then  
                oCollection.DeleteMembershipRule Rule  
            End If  
        End If  
    Next  
     
    WScript.Quit(0)

    Thursday, March 11, 2010 8:22 PM
  • Fantastic, well done.
    Thursday, March 11, 2010 10:14 PM
  • Hi Martin, your solution did not seem to work for me, but Jörgen's did work.
    Wednesday, March 17, 2010 5:42 AM
  • Martins script does work, its actually got an error in the script. Where he is setting up the arguments:

    Set oArguments = Wscript.Arguments

    ‘CollectionID from which to remove the comouter
    sCollectionID = objArguments.Named.Item("ID")
    sComputername = objArguments.Named.Item("ComputerName")

    As i noticed the "Set oArguments" is incorrect and just needs to be "objArguments" to coincide with the values below, or vice versa.

    Hope that helps.
    Matt Summer
    Wednesday, March 17, 2010 8:25 AM
  • Thanks Matt,

    problem is that I am not SCCM guy, nor do I have regular access to SCCM environment, so you should always carefully test those scripts before you try to run them :(

    Martin
    Wednesday, March 17, 2010 8:31 AM
  • Thanks Matt and Martin.

    Yeah, I only had them in a test environment and was looking to implement this in the production environment.  Will save me from doing this tedious admin task.

    I'm not much of a VBScript guy myself... nor much of an SCCM guy for that matter XD

    Cheers,
    Jerry
    Thursday, March 18, 2010 1:37 AM
  • Hi!

    It might be a good thing to point out that this also will trigger when program installation is done via Task Sequences (not only when using OSD) so you might want to write a check to verify what kind of collection it is you are about to remove the machine from. We use the simple way of checking a collection variable that we set to indicate that this collection is used for OSD, but there is probably more fancier ways to do this!

    Also, if you like us have different collections for different operating systems, it might be nice to dynamically verify that collection the machine should be removed from. A function like this can solve that:

    Function AdvertisementCollection(connection, machineName)

        Dim queryWQL
        Dim message
        Dim messageSet
        Dim statusMessage
        Dim insertionString
        Dim attributes
        Dim advertisement

        queryWQL = "SELECT b.Component, b.MachineName, b.MessageType, b.MessageID, " & _
                "       c.InsStrValue, d.AttributeValue " & _
                "FROM SMS_StatusMessage b " & _
                "     JOIN SMS_StatMsgInsStrings c ON b.RecordID = c.RecordID " & _
                "     JOIN SMS_StatMsgAttributes d ON c.RecordID = d.RecordID " & _
                "WHERE b.Component = 'Task Sequence Manager' AND b.MachineName = '" & machineName & "' AND d.AttributeID = 401 ORDER BY b.Time ASC"
       
        Set messageSet = connection.ExecQuery(queryWQL)
       
        For Each message in messageSet
           
            ' Get the message objects.
            attributes = message.Properties_.Item("d")
           
        Next                       

     Set advertisement = connection.Get("SMS_Advertisement.AdvertisementID='" & attributes.Properties_.Item("attributevalue") & "'")
     AdvertisementCollection = advertisement.CollectionID

     End Function

    Note that the connection input is swbemServices from the script above! As always test it in a lab before you implement it :-)

    Best regards,

    Jonas


    HeyHoo
    Friday, April 23, 2010 8:30 AM
  • I too would like to use this. I tried both your script suggestion but it does not remove the machine from the collection I specify. I copied the script on to my server, created a status filter rule with Task Manager Sequence (had to type this component in because it was not in the drop down list) and message id 11171, and triggered the script to run on the second tab. Am I missing something here? How can I verify that the script ran successful or not or even ran at all?
    Thursday, June 17, 2010 7:20 PM
  • I would start by selecting "Report to the Eventlog" in the status filter rule, then you know that the status filter rule is configured properly and working.

    If you log on to the sccm server with the correct permissions and trigger the vbscript, does it remove the computer from the collection then?

     


    ---------------------------------------------------- visit my System center blog at www.ccmexec.com
    Monday, June 21, 2010 7:04 AM
    Moderator
  • Okay, I added the 'Report to the Eventlog" option. Does this create a status message when the script runs? I also logged on the server with sccm admin rights and launched the vbscript but nothing happens. No errors and computers still exist in the osd collection. Here is the script. It was copied from your post above and the only thing I modified was the sCollectionID and also when I copied it, I had to change the single quote ‘ to ' and double quote “ to ". I appreciate your help. Thanks. btw this is on a Windows 2008 server OS.

     

    On Error Resume Next 
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection 
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet 
     
    Set oNetwork = CreateObject("WScript.NetWork")  

    'CollectionID from which to remove the comouter

    sCollectionID = "IPN00012"

    '————————————————————
    'Get Command Line arguments

    Set args = WScript.Arguments
    sComputername = args.Item(0)
    If sComputerName = NULL then
       wscript.quit
    End if

    '————————————————————
    'Main script

        Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
        swbemLocator.Security_.AuthenticationLevel = 6 'Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(".", "root\SMS")
        Set oProviderLocation = swbemServices.InstancesOf("SMS_ProviderLocation")
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, "root\sms\site_" + oLocation.SiteCode)
            End If      
        Next

    Set oCollection = SWbemServices.Get("SMS_Collection=’" & sCollectionID & "‘") 
     
    RuleSet = oCollection.CollectionRules 
     
    For Each Rule In RuleSet 
        If Rule.Path_.Class = "SMS_CollectionRuleDirect" Then 
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then 
                oCollection.DeleteMembershipRule Rule 
            End If 
        End If 
    Next 
     
    WScript.Quit(0)

    Wednesday, June 23, 2010 7:39 PM
  • ... launched the vbscript but nothing happens

    sComputername = args.Item(0)
    If sComputerName = NULL then
       wscript.quit
    End if

    How have you launched the script? It will exit if no argument was provided ...
    Thursday, June 24, 2010 7:28 AM
    Moderator
  • I also want to use the scripts. But I get allot of compilation errors regarding the '" and the ' characters. Does somebody now what is causing this? I tried to execute the scripts manually with the cscript command to see how it is working..

    Thanks

     

    Edit: Replaced all the ' and " characters.

    Edit2: The script executes succesfully but nothing seems to happen? 

    Tuesday, July 27, 2010 11:32 AM
  • Sorry for the late response, been busy with other things and this is a lower priority. But getting back to this script, I launched the script by logging into the SCCM server > Opening up Command prompt > then typing in cscript.exe E:\SCCMtools\remove.vbs %msgsys% I've also just tried double clicking the VBS. Both ways show me no errors and nothing happens. I've even removed

    sComputername = args.Item(0)
    If sComputerName = NULL then
       wscript.quit
    End if

    out of the script and same thing. Nothing happens with no errors. Does the server need rights to remove computers out of the collections?

    Thursday, July 29, 2010 3:26 PM
  • I tried to run Jörgen's and Martin's scripts but nothing happens. I also replaced all ' and " characters before I was able to launch the script. It seems that the trigger is working but the computer with the direct membership is still in the collection.

     

    Ruben's script from the third post works but I want to avoid using an username with password.

     

     

    Wednesday, August 11, 2010 11:14 AM
  • HI, all
    I have been using this script now in many implementations and I rewrote it a while ago, because the script i posted here uses the computername to match the direct membership rule. I have seen that third-party tools name the Direct Membership rules differently than the console, instead of computername it sometimes is blank. I have also come accross sceanrios where obsolete objects where removed instead of the active one.

    Here is an updated script which takes the computername from the variable and searches through all active objects in SCCM and then determines the ResourceID and uses that to remove the direct membership, solving the above issues.
    I hope this help you.

    Option Explicit

    Dim Args 
    Dim swbemLocator, SWbemServices, objCollection, oProviderLocation, oLocation  
    Dim strComputerName, arrComputers, objComputer, sCollectionID
    Dim objDirectRule

    On Error Resume Next 


    'CollectionID from which to remove the comouter

    sCollectionID = "0010004A" 

    '------------------------------------------------------------
    'Get Command Line arguments

    Set args = WScript.Arguments
    strComputername = args.Item(0)


    If strComputerName = NULL then
       wscript.quit
    End if

    '------------------------------------------------------------
    'Main script

        Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
        swbemLocator.Security_.AuthenticationLevel = 6 'Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(".", "root\SMS")
        Set oProviderLocation = swbemServices.InstancesOf("SMS_ProviderLocation")
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, "root\sms\site_" + oLocation.SiteCode)
            End If       
        Next

    Set objCollection = SWbemServices.Get("SMS_Collection='" & sCollectionID & "'")  
     
    Set arrComputers = SWbemServices.ExecQuery("select * from SMS_R_System where Name='" & strComputerName & "' and Obsolete = 0")

    For Each objComputer In arrComputers
       RemoveCollectionMembership objComputer.ResourceID
    Next

    objCollection.RequestRefresh false

    Set objCollection = Nothing

    Set SWbemServices = Nothing
    Set SWbemLocator = Nothing

    Wscript.Quit

    '------------------------------------------------
    Sub RemoveCollectionMembership(intresourceid)

    Set ObjDirectRule = SWbemServices.Get("SMS_CollectionRuleDirect").SpawnInstance_
    ObjDirectRule.ResourceID = intresourceid
    ObjCollection.DeleteMembershipRule objDirectRule

    End Sub
    WScript.Quit(0) 


    ---------------------------------------------------- visit my System center blog at www.ccmexec.com
    Wednesday, August 11, 2010 11:47 AM
    Moderator
  • Works perfectly for me. Thanks for posting.
    Wednesday, August 11, 2010 1:50 PM
  • Manually it is working correctly, but I also want to clean up the direct membership during a OSD deployment.

    I have created this Status Filter Trigger, as described above: 

    Create a Status Filter rule that will trigger on:
    Component : Task Sequence Manager
    Message ID: 11171 

    On the next page:
    save the script below on the sccm server and trigger the below script with something like:

    cscript.exe E:\SCCMtools\remove.vbs %msgsys

    ... but that isn't working (Also the component for Task Sequence Manager is not there), what is the best approach to execute this script and to clean up the settings after an OSD Deployment? 


    Wednesday, August 11, 2010 2:59 PM
  • Looking in the Eventviewer after an OSD deployment, the 11171 event ID is created, but the Task Category is saying "Unknown Compononent", I have deselected the Task Category to see if that can help. Or does somebody knows why it is saying that it is an "unknown component"?
    Thursday, August 12, 2010 7:19 AM
  • Thanks Jorgen. Your updated script does work for me now. However, I want to run this on multiple collections such as the capture and restore collections for USMT. I did see Martins post up above also but I'm unable to modify the script to make it work (I'm not a vbs guy). Any advice on applying this to multiple collections? Thanks in advance.
    Thursday, August 26, 2010 7:54 PM
  • Thanks Jörgen for posting this script. I just successfully tested it on one of my test collections.

    Pa Chou - I'm going to be running this script for multiple for collections. I'm not much of a scripter so what I plan on doing is have a script for every collection then a status filter rule for every script. It might not be the most efficient way but I'll be able to finally keep all my deployment collections clean.

    Wednesday, September 22, 2010 1:58 PM
  • That was my thought at first also but... after osd runs it reports the same status msg for the successful deployments (11171). If you have more than one status msg rule configured for 11171 doesn't it run only on the highest priority status filter rule? Or will it look at all the status filter rules that's configured with the 11171? Correct me if I'm wrong but that's why I was asking about having one script that will look in multiple collections.
    Wednesday, October 13, 2010 5:19 PM
  • I need to adapt the script to search for all collections, but I can't figure out how to do that in a script, we have about 50 collections we use for builds, collections are based on location & region, we have a lot of offices worldwide but I need a way to remove the computer from any direct memberships, can anyone assist?

     

    Thursday, October 21, 2010 3:33 PM
  • Hi,
    Sorry for the late answer.

    This updated script will make it possible for you to delete the computer from mutiple collections.

     
    Option Explicit
    ' Constants for type of event log entry
    const EVENTLOG_INFORMATION = 4


    Dim Args 
    Dim swbemLocator, SWbemServices, objCollection, oProviderLocation, oLocation  
    Dim strComputerName, arrComputers, objComputer, sCollectionIDs
    Dim objDirectRule
    Dim strmessage, objshell
    Dim seventlog, sClearPxeflag

    On Error Resume Next 


    'CollectionIDs from which to remove the computer
    'Should an eventlog entry be generated, set Seventlog=1

    sEventlog = "1"
    sCollectionIDs = "0010004c:0010007F:00100069" 

    '------------------------------------------------------------
    'Get Command Line arguments

    Set args = WScript.Arguments
    strComputername = args.Item(0)


    If strComputerName = NULL then
       wscript.quit
    End if

    '------------------------------------------------------------
    'Main script

    set objShell = CreateObject("WScript.Shell")

        Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
        swbemLocator.Security_.AuthenticationLevel = 6 'Packet Privacy.
        Set swbemServices = swbemLocator.ConnectServer(".", "root\SMS")
        Set oProviderLocation = swbemServices.InstancesOf("SMS_ProviderLocation")
        For Each oLocation In oProviderLocation
            If oLocation.ProviderForLocalSite = True Then
                Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, "root\sms\site_" + oLocation.SiteCode)
            End If       
        Next

    Set arrComputers = SWbemServices.ExecQuery("select * from SMS_R_System where Name='" & strComputerName & "' and Obsolete = 0")

    For Each objComputer In arrComputers
       RemoveCollectionMembership objComputer.ResourceID
      
    'Write to eventlog if Seventlog = 1  
       If Seventlog = "1" then
       strMessage = strcomputername & " will be removed from the following collection ID's " & scollectionids
       objShell.LogEvent EVENTLOG_INFORMATION, strMessage
       End IF
      
    Next


    Set objCollection = Nothing
    Set SWbemServices = Nothing
    Set SWbemLocator = Nothing


    Wscript.Quit


    '------------------------------------------------
    Sub RemoveCollectionMembership(intresourceid)

    Dim mCollectionID, i
    mCollectionID = Split (sCollectionIDs, ":")
    for i = Lbound(mCollectionID) to UBound(mCollectionID)

     Set objCollection = SWbemServices.Get("SMS_Collection='" & MCollectionID(i) & "'")
     Set ObjDirectRule = SWbemServices.Get("SMS_CollectionRuleDirect").SpawnInstance_
     ObjDirectRule.ResourceID = intresourceid
     ObjCollection.DeleteMembershipRule objDirectRule
    next
    End Sub

     

    '------------------------------------------------

     

    WScript.Quit(0) 


    -- visit my System center blog at http://ccmexec.com --
    Tuesday, November 16, 2010 12:17 PM
    Moderator
  • Thanks Jörgen!


    This solution works, when the computer is in each of the defined collections.

     

    I have noticed that when the compuer ist not in the first collection the scipt ends. So when i have a computer which is only in the second Cllections, the script ends before it reaches the second collection.

    Do you have a solution for this case?

    Monday, December 6, 2010 9:00 AM
  • Hi, good to hear i works :-)

    If you just add a line

    On Error Resume Next

    In the Sub so it looks like this it will work even if the computer is not member of all Collections.

    '------------------------------------------------
    Sub RemoveCollectionMembership(intresourceid)

    On Error Resume Next

    Dim mCollectionID, i
    mCollectionID = Split (sCollectionIDs, ":")
    for i = Lbound(mCollectionID) to UBound(mCollectionID)

     Set objCollection = SWbemServices.Get("SMS_Collection='" & MCollectionID(i) & "'")
     Set ObjDirectRule = SWbemServices.Get("SMS_CollectionRuleDirect").SpawnInstance_
     ObjDirectRule.ResourceID = intresourceid
     ObjCollection.DeleteMembershipRule objDirectRule
    next
    End Sub

    Regards,
    Jörgen


    -- visit my System center blog at http://ccmexec.com --
    Wednesday, December 8, 2010 2:18 PM
    Moderator
  • Got a weird issue with the following script after migrating to Native Mode:

     

    On Error Resume Next
    Dim oNetwork, oLocator, oSWbemServices, oCollection
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet
    Set oNetwork = CreateObject("WScript.NetWork")
    'CollectionID from which to remove the computer
    sCollectionID = "MHS0002D"
    '————————————————————
    'Get Command Line arguments
    Set args = WScript.Arguments
    sComputername = args.Item(0)
    If sComputerName = NULL then
    wscript.quit
    End if
    '————————————————————
    'Main script
    Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
    swbemLocator.Security_.AuthenticationLevel = 6 'Packet Privacy.
    Set swbemServices = swbemLocator.ConnectServer(".", "root\SMS")
    Set oProviderLocation = swbemServices.InstancesOf("SMS_ProviderLocation")
    For Each oLocation In oProviderLocation
    If oLocation.ProviderForLocalSite = True Then
    Set swbemServices = swbemLocator.ConnectServer(oLocation.Machine, "root\sms\site_" + oLocation.SiteCode)
    End If
    Next
    Set oCollection = SWbemServices.Get("SMS_Collection='" & sCollectionID & "'")
    RuleSet = oCollection.CollectionRules
    For Each Rule In RuleSet
    If Rule.Path_.Class = "SMS_CollectionRuleDirect" Then
    If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then
    oCollection.DeleteMembershipRule Rule
    End If
    End If
    Next
    WScript.Quit(0)
    
    
    

    As I work in a school, I have 3 Deployment collections - Office Staff, Pupils, Teaching Staff

    The script works for Computers in the Office Staff collection, but not the other 2 - meaning the computers get stuck in a rebuild loop until the computer is removed from the collection.

    I have 3 copies of the script above, each with the correct CollectionID in them and 3 status filter rules for event id 11171 each pointing to the correct VBScripts..

    Anyone know why only one script works and not the other two?

    Tuesday, January 11, 2011 8:37 AM
  • The script works for Computers in the Office Staff collection, but not the other 2 - meaning the computers get stuck in a rebuild loop until the computer is removed from the collection.
    Why is the computer stuck in a rebuild loop? ConfigMgr usually handles that itself by setting the PXE advertisement flag: http://msdn.microsoft.com/en-us/library/cc143002.aspx (when using a mandatory advertisement). So there's no need for such a script by default.
    You could monitor smsprov.log if there are any errors when the script is launched for the other 2 collections. You might also have to add logging to the script to see what's going on behind the scenes.
    Why using 3 collections (which implies 3 different advertisements and tasksequences)? Can't you use just one TS (with variables and conditions)?
    Tuesday, January 11, 2011 8:53 AM
    Moderator
  • Something of note:

    If anyone wants to use one of the intial scripts above - the one that has username and password, just pass those as 'parameters' (arguments) - that way, you don't have to include the username/password IN the code.

    Thursday, February 3, 2011 9:35 PM
  • No, there is really a need for a workaround, it's a design problem IMHO.

    The computer stucks in a rebuild loop, because ConfigMgr starts the TS now in Full OS and pre-stages WinPE. In this scenario the Computer will never ever need PXE anymore for the TS, so the PXE Flag is useless.

     

    I think it's a problem by design.

    Why doesn't the Client save this execution history?

    Wednesday, March 9, 2011 12:33 PM
  • Manually it is working correctly, but I also want to clean up the direct membership during a OSD deployment.

    I have created this Status Filter Trigger, as described above: 

    Create a Status Filter rule that will trigger on:
    Component : Task Sequence Manager
    Message ID: 11171 

    On the next page:
    save the script below on the sccm server and trigger the below script with something like:

    cscript.exe E:\SCCMtools\remove.vbs %msgsys

    ... but that isn't working (Also the component for Task Sequence Manager is not there), what is the best approach to execute this script and to clean up the settings after an OSD Deployment? 


    Create a Status Filter rule that will trigger on:
    Component : Task Sequence Manager
    Message ID: 11171 

    We have SCCM 2007 SP2 R3, the script works great if i run it manually providing the machine name to remove from our rebuild collection, however when i set it up as a Status Filter Rule the componet "Task Sequence Manager" is not available in the list??

    I have SMS_STATUS_MANAGER but nothing for task sequences, which is weird as the log states the Component that generated the event 11171 as Task Sequence Manager...

    Is their another component i can use to trigger this script?

    Monday, March 14, 2011 7:59 PM
  • Hi,

    The reason why you have to type in the Component name manually is that it is not a server component so it is not known in the console.
    You could schedule the script using a schedule task but it is not as pretty. ;-)

    I have posted an updated version here which can remove from more than one collection and write to the event-log.

    http://ccmexec.com/?p=4

    Regards,
    Jörgen


    -- visit my System center blog at http://ccmexec.com --
    • Proposed as answer by Pa Chou Tuesday, October 4, 2011 4:32 PM
    Monday, March 14, 2011 8:09 PM
    Moderator
  • You can manually type  Task Sequence Manager into the field
    Tuesday, March 15, 2011 7:09 AM
  • Typed it in and it worked a treat,  I like the simple answers..

    Thanks

    Tuesday, March 15, 2011 10:42 PM
  • @jörgen

    Very good job. This was something what I missed so far.

    now I can create the pipe to automatize the AD application group creation for installation and uninstallaiton softwrae distribution packages. This includes also the removal of them in the moment when the sccm softwrae distribution packages gets obsolete (manually delete process according to a CR)!

    Thanks for the details on your website...fantastic!

     


    Tarkan Koemuercue
    Sunday, June 19, 2011 7:48 PM
  • Hello All! The above scripts seem to be working fine but...manually. If I go on the server and I type in a CMD cscript.exe c:\scripts\RemoveComputerAfterOSD.vbs COMPUTER , I check in the SCCM server log and get the following message

    COMPUTER will be removed from the following collection ID's AAA00173:AAA0016B:AAA0016C. I have confirmed in the collection that the computer item gets deleted.

    But for some reason, it doesn't seem to trigger automatically via the Status Filter Rule? I have checked in the event log of the server and don't see any Task Sequence Manager item? Also, when I added this in the Status Filter Rule in the Component's drop down menu, that item was not there, I had to type it manually. Could it be possible that Task Sequence Manager logging is not enabled? and if so, how could I enable it ?


    We are using SCCM 2007 R2

     

    Thanks for all the input you can bring! :)

     

    Monday, July 18, 2011 12:40 PM
  • Just a wild guess (without having a ConfigMgr console in front of me): check if http://technet.microsoft.com/en-us/library/bb632825.aspx is set to "all milestone and all details"
    Torsten Meringer | http://www.mssccmfaq.de
    Monday, July 18, 2011 3:54 PM
    Moderator
  • Here is blog on this subject that you might want to check out

    http://blog.danovich.com.au/2010/03/12/remove-computer-association-from-collection-after-sccm-task-sequence/

     


    http://www.sccm-tools.com http://sms-hints-tricks.blogspot.com
    Monday, July 18, 2011 5:54 PM
    Moderator
  • I enabled the"All Milestone and All Details" for the client Component. Now I can see the Task Sequence log in the event viewer but the Category appears as "Unknown Component". Any idea on why it isn't getting the name "Task Sequence Manager" (it appears OK when I open the event log though :

     

    On 07/18/11 14:33:46, component Task Sequence Manager on computer XXXXX reported: The task sequence manager successfully completed execution of the task sequence.

    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

     

    Should I just modify the Status Filter Rule to "Unknown Component", with ID 11171 instead of Task Sequence Manager... I know it is not really clean but I can't figure out how to make Unknown Component to become Task Sequence Manager... Any help of solving this second issue would be appreciated, and I think I'd be OK now with auto deleting computers :)

    Monday, July 18, 2011 7:27 PM
  • Can't you just use ID 11171 without a specifying a component? (Still got no console next to me :-) )


    Torsten Meringer | http://www.mssccmfaq.de
    Monday, July 18, 2011 7:38 PM
    Moderator
  • Hi,
    Just use the ID as Torsten pointed out it will work aswell..

    Regards,
    Jörgen


    -- My System Center blog ccmexec.com --
    Tuesday, July 19, 2011 7:45 AM
    Moderator
  • Over 2 years old this post and still going, got to be some sort of record surely ;-)


    Matt Summer
    Tuesday, July 19, 2011 10:35 AM
  • Worked like a charm just using ID 11171...Still don't know why "Task Sequence Manager" doesn't appear there but at least it works...I also checked in the logs and there are not other events that seem to be associated with 11171 so I guess I will be OK with that!

    A big thanks for your help !

    Wednesday, July 20, 2011 2:03 PM
  • Hello!

    I tried to run some of the mentioned scripts, but to no result, they memberships are still there.

    What I need is a script that will be triggered manually, get's the collection ID as a parameter, and deletes all membership rules for that collection.

    Could You please past it in this form?

    Thursday, September 15, 2011 1:06 PM
  • Jorgen's script works perfectly. Go here http://ccmexec.com/?p=4 and follow his instructions. Remember you hhave to modify the collection ID's in the script.

     

    Thanks a bunch Jorgen.

     

     

    Tuesday, October 4, 2011 4:32 PM
  • Do i have to apply this filter to All sites that can perform OSD? For example the Central, Primary's and child sites?
    Friday, February 3, 2012 6:24 PM
  • I used the code below and changed the specifics to my environment.  I put in my SMS server, site code, collection ID, my username/pass and also identified a specific computer name for testing purposes.  The script runs successfully without any errors but the object doesn't get deleted.  I can't figure out where its going wrong.  I updated collection membership and refreshed everything, but no dice, the computer object is still there.  I don't know if it makes a difference, but the object I am trying to delete was manually created by me for testing purposes.  

    I am running the script manually from the SCCM server using cscript, this is NOT part of a task sequence.  I just want people to be able to remove SCCM objects via script (and eventually a front end) instead of going into the console.

    You could add a step at the very end of the task sequence running a vb-script that removes the resource from the collection, something like the following:

    On Error Resume Next  
     
    Dim oNetwork, oLocator, oSWbemServices, oCollection  
    Dim sComputerName, sSMSServer, sSMSSiteCode, sCollectionID, RuleSet  
     
    Set oNetwork = CreateObject("WScript.NetWork")   
     
    sComputerName = oNetwork.ComputerName  
    sSMSServer = "SCCM" 
    sSMSSiteCode = "CEN" 
    sCollectionID = "CEN00001" 
    sUserName = "Domain\Username" 
    sUserPassword = "Password" 
     
    Set oLocator = CreateObject("WbemScripting.SWbemLocator")  
    oLocator.Security_.AuthenticationLevel = 6 
    Set oSWbemServices = oLocator.ConnectServer(sSMSServer, "root\sms\site_" & sSMSSiteCode, sUserName, sUserPassword)  
    Set oCollection = oSWbemServices.Get("SMS_Collection='" & sCollectionID & "'")  
     
    RuleSet = oCollection.CollectionRules  
     
    For Each Rule In RuleSet  
        If Rule.Path_.Class = "SMS_CollectionRuleDirect" Then  
            If LCase(Trim(Rule.RuleName)) = LCase(Trim(sComputerName)) Then  
                oCollection.DeleteMembershipRule Rule  
            End If  
        End If  
    Next  
     
    WScript.Quit(0) 


    Just make sure the user you use has the apropriate rights in SCCM (rights on collection + connect rights), you probably should make it a service account that can't log on and strip it of every other right it doesn't need as the password is clear text and somone could possibly snatch it.


    Monday, February 13, 2012 10:05 PM
  • Hi guys, I wanted to know if there is a way to change the colleciton ID from the script to use a TS variable or collection variable.

    Thank You!

    Mathieu


    • Edited by mdesjardins Wednesday, April 4, 2012 8:38 PM
    Wednesday, April 4, 2012 5:16 PM
  • We used another way to do it.

    We are using some queries to verify if the computer is member of the install collection and if the software is still there. If none apply, he is removed.

    Thursday, April 26, 2012 7:17 PM
  • I'm going to use Jorgen's script to delete PCs from all SCCM collections by ResourceID.

    I've also been asked to write or modify a script that will delete a PC from all collections by Direct Membership.  I see Jorgen has provided a script to delete a PC from ONE collection; I'm wondering if it's possible to modify that script so it would remove a PC via Direct Membership from MULTIPLE collections.

    Thanks.

    Monday, September 10, 2012 9:10 PM
  • Hi,

    the latest version I posted can be used to remove a computer from multiple collections as well as clear the PXE flag: http://ccmexec.com/2012/07/remove-from-collection-and-clear-pxe-flag-vbscript-using-status-filter-rule/

    Just modify the following to include all collectionIDs you want the computer removed from

    sCollectionIDs = “00100053:0010004A:00100069″

    I hope it helps

    Regards,
    Jörgen


    -- My System Center blog ccmexec.com -- Twitter @ccmexec

    Monday, September 10, 2012 9:20 PM
    Moderator
  • I have a little issue with the script icw SCCM2012.

    The script runs perfectly and also removes the computer (almost instantly) from the collection. The computer reboots after the TS is finished. After a minute the computer is reinstalling for the second time. After the second installation the computer stopped reinstalling

    It looks like the SCCM2012 client is very fast getting it's policies during the startup.....so fast that the account deletion is not quick enough. I was wondering if I'm the only one with this issue.


    Thursday, April 11, 2013 2:41 PM
  • I have a little issue with the script icw SCCM2012.

    The script runs perfectly and also removes the computer (almost instantly) from the collection. The computer reboots after the TS is finished. After a minute the computer is reinstalling for the second time. After the second installation the computer stopped reinstalling

    It looks like the SCCM2012 client is very fast getting it's policies during the startup.....so fast that the account deletion is not quick enough. I was wondering if I'm the only one with this issue.


    I've created the following solution for those who struggle with the same issues (a reinstall loop because the removal of the computer from the collection isn't going fast enough):

    - Create a script with that causes a delay and executes a new client machine policy check.
    - Create a package of the script without deploying it (make sure you allow the package to run from a TS)
    - Go to the TS of the OSD and hit the properties
    - Use the 'Run Another Program First' option and select the package to run before the actual (unwanted) OSD starts
    - Do not select 'Always Run this Program First' to make sure it only runs once

    Here is an example of my 'delay script' that is causing an extra machine policy check. The script should provide enough time to stop the unwanted reinstall loop:

    powershell.exe Start-transcript -path c:\reinstall.txt;start-sleep -s 170;([wmiclass]'\\.\root\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000021}');start-sleep -s 10;stop-transcript

    I start the powershell commands from a batch file because we do not allow PS scripts (yet).

    Hope this solution will contribute something to your environment.

    Monday, April 15, 2013 1:47 PM
  • In our SCCM there is hundreds of AD discovery object with SCCM client agent status as "No"

    WE need to avoid this machines appear in the SCCm console when the compliant inventry happen

    So I am looking a solution to delete these AD discovery object from all collection using a script that can be execute via Task Sheduler daily after the AD discovery happened

    I ahve checked this script by  but facing issue that it not happening

    I have changed the Collection ID used below command .Am I doing any mistakes please help me

    sCollectionID = "WGP0045D"

    I am getting error saying below

    Line 6

    Char 29

    invalid character

    microsoft vbscript compailaisation error


    shinu




    please help me it is urgent for me
    • Edited by shinub Friday, February 13, 2015 1:07 PM
    Friday, February 13, 2015 12:15 PM