请求开发SCCM桌面刷新PowerShell脚本:新设备继承旧设备集合
Got it, let's tackle this scenario where you need to sync device collections between old and new leased PCs during a desktop refresh. This is a common task to ensure new devices inherit all the right groupings—especially those critical patch cycle collections that prevent entire sites or departments from going offline during patching. Here's a practical PowerShell solution tailored to your needs:
Prerequisites
First, make sure you have these in place before running the script:
- The Configuration Manager PowerShell module installed (typically found at
C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1) - Permissions to read device collections and add devices to them
- Identifiers for your old and new devices (device names, resource IDs, or UUIDs work)
Core Script
This script will pull all collections the old device is part of, then add the new device to each of those collections (excluding default system collections to avoid unnecessary additions):
# Load the Configuration Manager module $modulePath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" Import-Module $modulePath -ErrorAction Stop # Set your ConfigMgr site code (replace "XYZ:" with your actual site code) $siteCode = "XYZ:" Set-Location $siteCode -ErrorAction Stop # Define your old and new device names (replace with actual device identifiers) $oldDeviceName = "OLD-PC-01" $newDeviceName = "NEW-PC-01" # Get the old device's resource ID (unique identifier in ConfigMgr) $oldDevice = Get-CMDevice -Name $oldDeviceName -ErrorAction Stop $oldResourceId = $oldDevice.ResourceID # Fetch all collections the old device is a member of Write-Host "Retrieving collections for old device: $oldDeviceName" $deviceCollections = Get-CMDeviceCollectionMember -ResourceId $oldResourceId | Select-Object -ExpandProperty CollectionID | Get-CMDeviceCollection # Filter out default system collections (adjust this to fit your needs) $filteredCollections = $deviceCollections | Where-Object { $_.Name -notlike "*All Systems*" -and $_.Name -notlike "*All Desktop and Server Clients*" } # Get the new device's resource ID $newDevice = Get-CMDevice -Name $newDeviceName -ErrorAction Stop $newResourceId = $newDevice.ResourceID # Add the new device to each filtered collection foreach ($collection in $filteredCollections) { try { Write-Host "Adding $newDeviceName to collection: $($collection.Name)" Add-CMDeviceCollectionDirectMembershipRule -CollectionId $collection.CollectionID -ResourceId $newResourceId -ErrorAction Stop Write-Host "Successfully added to $($collection.Name)`n" } catch { Write-Warning "Failed to add $newDeviceName to $($collection.Name): $_`n" } } Write-Host "Collection sync complete! $newDeviceName is now part of all collections that $oldDeviceName belonged to."
Customization Tips
- Explicitly Target Patch Cycle Collections: If you want to only sync the 5 patch cycle collections (instead of all), modify the
Where-Objectclause to include their names explicitly:$filteredCollections = $deviceCollections | Where-Object { $_.Name -in @("Patch Cycle 1", "Patch Cycle 2", "Patch Cycle 3", "Patch Cycle 4", "Patch Cycle 5") } - Batch Processing: For multiple device pairs, read from a CSV file (with columns
OldDeviceandNewDevice) using this modified script:# Load Configuration Manager module $modulePath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" Import-Module $modulePath -ErrorAction Stop $siteCode = "XYZ:" Set-Location $siteCode -ErrorAction Stop # Read device pairs from CSV $devicePairs = Import-Csv -Path "C:\IT\DesktopRefresh\DevicePairs.csv" foreach ($pair in $devicePairs) { $oldDeviceName = $pair.OldDevice $newDeviceName = $pair.NewDevice try { $oldDevice = Get-CMDevice -Name $oldDeviceName -ErrorAction Stop $oldResourceId = $oldDevice.ResourceID $deviceCollections = Get-CMDeviceCollectionMember -ResourceId $oldResourceId | Select-Object -ExpandProperty CollectionID | Get-CMDeviceCollection $filteredCollections = $deviceCollections | Where-Object { $_.Name -notlike "*All Systems*" -and $_.Name -notlike "*All Desktop and Server Clients*" } $newDevice = Get-CMDevice -Name $newDeviceName -ErrorAction Stop $newResourceId = $newDevice.ResourceID foreach ($collection in $filteredCollections) { Add-CMDeviceCollectionDirectMembershipRule -CollectionId $collection.CollectionID -ResourceId $newResourceId -ErrorAction Stop Write-Host "Added $newDeviceName to $($collection.Name)" } } catch { Write-Warning "Failed to process $oldDeviceName -> $newDeviceName: $_" } } - Alternative Device Identifiers: If you use UUIDs instead of device names, replace
-Name $oldDeviceNamewith-UUID $oldDeviceUuidin theGet-CMDevicecalls.
内容的提问来源于stack exchange,提问作者Matthew Patterson

