Jump to content


Spinner

Powershell Script to Copy 1 Computer Collection Membership 7 Apply to Another

Recommended Posts

Hi All,

 

I've been googling and can find the opposite of what i'm looking for so was wondering if i could get some help.

 

Basically what i'm after is a Powershell script that will get the collections that 1 pc is a member off and then add another pc to those same collections (preferably via a prompt)

 

We have some PC's at the moment that will be out of lease and replaced and they have computer deployed applications so i was hoping to mirror the same collection membership for the new PC they get to make it easier. Also we get requests that 1 user needs the same apps as another where this would also come in handy.

 

Hopefully a powershell guru would be able to assist me :)

 

 

 

Thanks,

 

Spinner

Share this post


Link to post
Share on other sites


So far i can't seem to get anything working that i've found, only thing i've got so far is the right click tools and copy pasting that into excel

Share this post


Link to post
Share on other sites

Well, to be quite honest, it can't be that difficult.... You can get cmdlets for membership rules to get the information and use the add cmdlets to add the membership rules. Those cmdlets are all described here:

https://technet.microsoft.com/en-us/library/jj821831%28v=sc.20%29.aspx

Share this post


Link to post
Share on other sites

That should do the trick

param(
    [parameter(Mandatory = $true)]
    [string]$SiteServer,
    [parameter(Mandatory = $true)]
    [string]$SiteCode,
    [parameter(Mandatory = $true)]
    [string]$ReferenceMachine,
    [parameter(Mandatory = $true)]
    [string]$ReplacementMachine
)

Import-Module -Name "$(split-path $Env:SMS_ADMIN_UI_PATH)\ConfigurationManager.psd1"

$location = $SiteCode + ":"

Set-Location -Path $location

if(Get-CMDevice -Name $ReferenceMachine){
    if(Get-CMDevice -Name $ReferenceMachine){
        $ReplacementID = (Get-CMDevice -Name $ReplacementMachine).ResourceID
        $ResID = (Get-CMDevice -Name $ReferenceMachine).ResourceID
        Get-WmiObject -ComputerName $SiteServer -Class sms_fullcollectionmembership -Namespace root\sms\site_$SiteCode -Filter "ResourceID = '$($ResID)'"  | % {
            if(Get-CMDeviceCollectionDirectMembershipRule -CollectionID $_.CollectionID -ResourceName $ReferenceMachine){
                Write-Host "adding" $ReplacementMachine "to collection" $_.CollectionID
                Add-CMDeviceCollectionDirectMembershipRule -CollectionId $_.CollectionID -ResourceId $ReplacementID
            }
        }
    }
    else {
        Write-Host "Error. Unknown replacement machine :" $ReplacementMachine
    }
}
else {
    Write-Host "Error. Unknown reference machine :" $ReferenceMachine
}

Share this post


Link to post
Share on other sites

Thanks Pete i'll give it a go, so far i only had this:

$Server = "SERVER"
$site = "HQ2"

Function Get-Collections 
{
    <# 
            .SYNOPSIS 
                Determine the SCCM collection membership    
            .DESCRIPTION
                This function allows you to determine the SCCM collection membership of a given user/computer
            .PARAMETER  Type 
                Specify the type of member you are querying. Possible values : 'User' or 'Computer'
            .PARAMETER  ResourceName 
                Specify the name of your member : username or computername
            .EXAMPLE 
                Get-Collections -Type computer -ResourceName PC001
                Get-Collections -Type user -ResourceName User01
            .Notes 
                Author : Antoine DELRUE 
                WebSite: http://obilan.be 
    #> 

    param(
    [Parameter(Mandatory=$true,Position=1)]
    [ValidateSet("User", "Computer")]
    [string]$type,

    [Parameter(Mandatory=$true,Position=2)]
    [string]$resourceName
    ) #end param

    Switch ($type)
        {
            User {
                Try {
                    $ErrorActionPreference = 'Stop'
                    $resource = Get-WmiObject -ComputerName $server -Namespace "root\sms\site_$site" -Class "SMS_R_User" | ? {$_.Name -ilike "*$resourceName*"}                            
                }
                catch {
                    Write-Warning ('Failed to access "{0}" : {1}' -f $server, $_.Exception.Message)
                }

            }

            Computer {
                Try {
                    $ErrorActionPreference = 'Stop'
                    $resource = Get-WmiObject -ComputerName $server -Namespace "root\sms\site_$site" -Class "SMS_R_System" | ? {$_.Name -ilike "$resourceName"}                           
                }
                catch {
                    Write-Warning ('Failed to access "{0}" : {1}' -f $server, $_.Exception.Message)
                }
            }
        }

    $ids = (Get-WmiObject -ComputerName $server -Namespace "root\sms\site_$site" -Class SMS_CollectionMember_a -filter "ResourceID=`"$($Resource.ResourceId)`"").collectionID
    # A little trick to make the function work with SCCM 2012
    if ($ids -eq $null)
    {
            $ids = (Get-WmiObject -ComputerName $server -Namespace "root\sms\site_$site" -Class SMS_FullCollectionMembership -filter "ResourceID=`"$($Resource.ResourceId)`"").collectionID
    }

    $array = @()

    foreach ($id in $ids)
    {
        $Collection = get-WMIObject -ComputerName $server -namespace "root\sms\site_$site" -class sms_collection -Filter "collectionid=`"$($id)`""
        $Object = New-Object PSObject
        $Object | Add-Member -MemberType NoteProperty -Name "Collection Name" -Value $Collection.Name
        $Object | Add-Member -MemberType NoteProperty -Name "Collection ID" -Value $id
        $Object | Add-Member -MemberType NoteProperty -Name "Comment" -Value $Collection.Comment
        $array += $Object
    }

    $array
}
Get-Collections -Type computer -ResourceName PC007

Share this post


Link to post
Share on other sites

I added a confirmation prompt for the memberships.


param(
    [parameter(Mandatory = $true)]
    [string]$SiteServer,
    [parameter(Mandatory = $true)]
    [string]$SiteCode,
    [parameter(Mandatory = $true)]
    [string]$ReferenceMachine,
    [parameter(Mandatory = $true)]
    [string]$ReplacementMachine
)

Import-Module -Name "$(split-path $Env:SMS_ADMIN_UI_PATH)\ConfigurationManager.psd1"

$location = $SiteCode + ":"

Set-Location -Path $location

if(Get-CMDevice -Name $ReferenceMachine){
    if(Get-CMDevice -Name $ReferenceMachine){
        $ReplacementID = (Get-CMDevice -Name $ReplacementMachine).ResourceID
        $ResID = (Get-CMDevice -Name $ReferenceMachine).ResourceID
        Get-WmiObject -ComputerName $SiteServer -Class sms_fullcollectionmembership -Namespace root\sms\site_$SiteCode -Filter "ResourceID = '$($ResID)'" | % {
            if(Get-CMDeviceCollectionDirectMembershipRule -CollectionID $_.CollectionID -ResourceName $ReferenceMachine){
                $colname = (Get-CMDeviceCollection -CollectionId $_.CollectionID).Name
                if(!(Get-CMDeviceCollectionDirectMembershipRule -CollectionID $_.CollectionID -ResourceName $ReplacementMachine)){
                    $confirm = Read-Host "Do you want to add $ReplacementMachine to the collection" $_.CollectionID "'$colname' ? (y/n) "
                    if($confirm -eq "y"){
                        Write-Host "adding $ReplacementMachine to collection" $_.CollectionID "'$colname'"
                        Add-CMDeviceCollectionDirectMembershipRule -CollectionId $_.CollectionID -ResourceId $ReplacementID
                    }
                    else {
                        Write-Host "skipping collection $colname"
                    }
                }
                else {
                    Write-Host "$ReplacementMachine is already a member of" $_.CollectionID "'$colname'"
                }
            }
        }
    }
    else {
        Write-Host "Error. Unknown replacement machine : $ReplacementMachine"
    }
}
else {
    Write-Host "Error. Unknown reference machine : $ReferenceMachine"
}

Share this post


Link to post
Share on other sites

I know this is old but there are surprisingly few resources related to this task, which I would have thought would be very valuable in a replacement scenario.

 

However, this script is kind of difficult to utilize for large numbers of computers.

 

Instead, I think something that would copy collections from ALL source computers in the computer association list to all destination computers in the list would be a lot better for mass replacement scenarios.

 

I don't suppose anyone has a starting point or any work related to a script that would copy collections from all source to all destination computers in the association list in SCCM?

 

Thanks

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...