请求基于VBS/PS实现SCCM设备EOL迁移全流程自动化
Got it, let's tackle this SCCM device EOL automation task with PowerShell—it's far more intuitive and powerful than VBS for this kind of management workflow. Below is a complete, step-by-step solution that covers all your requirements: retrieving the old device's collections, migrating membership to the new device, removing the old device, and generating an audit report.
Prerequisites
- Run PowerShell with administrative privileges that have SCCM collection modification rights.
- If you're on the SCCM site server, the ConfigMgr module is available by default. If running remotely, import it via:
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" - Switch to your SCCM site drive first (e.g.,
PS X:\>where X is your site code drive).
Full Script with Annotations
# -------------------------- # Configuration Section - Update these values! # -------------------------- $oldDeviceName = "IN-00001236" $newDeviceName = "IN-1111" $reportPath = "C:\SCCM_EOL_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" # -------------------------- # Step 1: Locate the Old Device & Its Collections # -------------------------- # Get the old device's ResourceID (required for SCCM membership queries) $oldDevice = Get-CMDevice -Name $oldDeviceName if (-not $oldDevice) { Write-Error "Old device $oldDeviceName not found in SCCM. Exiting." exit 1 } # Fetch all collections the old device is a direct member of $deviceCollections = Get-CMDeviceCollectionMember -CollectionId * | Where-Object { $_.ResourceID -eq $oldDevice.ResourceID } if ($deviceCollections.Count -eq 0) { Write-Warning "Old device $oldDeviceName isn't part of any collections. Nothing to do." exit 0 } # Extract unique collection details to avoid duplicate operations $collectionList = $deviceCollections | Select-Object CollectionID, CollectionName -Unique Write-Host "Found $($collectionList.Count) collections for old device: $($collectionList.CollectionName -join ', ')" # -------------------------- # Step 2: Validate New Device Exists in SCCM # -------------------------- $newDevice = Get-CMDevice -Name $newDeviceName if (-not $newDevice) { Write-Error "New device $newDeviceName not found in SCCM. Exiting." exit 1 } # -------------------------- # Step 3: Add New Device to All Target Collections # -------------------------- $addResults = @() foreach ($collection in $collectionList) { try { Add-CMDeviceCollectionDirectMembershipRule -CollectionId $collection.CollectionID -ResourceId $newDevice.ResourceID $addResults += [PSCustomObject]@{ CollectionID = $collection.CollectionID CollectionName = $collection.CollectionName Action = "Added New Device" Status = "Success" Message = "$newDeviceName added to $($collection.CollectionName)" } Write-Host "✅ Successfully added $newDeviceName to $($collection.CollectionName)" } catch { $addResults += [PSCustomObject]@{ CollectionID = $collection.CollectionID CollectionName = $collection.CollectionName Action = "Added New Device" Status = "Failed" Message = $_.Exception.Message } Write-Error "❌ Failed to add $newDeviceName to $($collection.CollectionName): $_" } } # -------------------------- # Step 4: Remove Old Device from All Target Collections # -------------------------- $removeResults = @() foreach ($collection in $collectionList) { try { Remove-CMDeviceCollectionDirectMembershipRule -CollectionId $collection.CollectionID -ResourceId $oldDevice.ResourceID -Force $removeResults += [PSCustomObject]@{ CollectionID = $collection.CollectionID CollectionName = $collection.CollectionName Action = "Removed Old Device" Status = "Success" Message = "$oldDeviceName removed from $($collection.CollectionName)" } Write-Host "✅ Successfully removed $oldDeviceName from $($collection.CollectionName)" } catch { $removeResults += [PSCustomObject]@{ CollectionID = $collection.CollectionID CollectionName = $collection.CollectionName Action = "Removed Old Device" Status = "Failed" Message = $_.Exception.Message } Write-Error "❌ Failed to remove $oldDeviceName from $($collection.CollectionName): $_" } } # -------------------------- # Step 5: Generate Audit Report # -------------------------- $fullReport = $addResults + $removeResults $fullReport | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8 Write-Host "`nEOL process completed! Audit report saved to: $reportPath"
Key Notes for Production Use
- Direct vs. Query-Based Collections: This script handles direct membership rules only. If the old device is in query-driven collections, you'll need to adjust the script to modify collection queries (though this is less common for device-specific EOL tasks).
- Excel Format Option: If you need an Excel report instead of CSV, install the
ImportExcelmodule (Install-Module -Name ImportExcel) and replaceExport-CsvwithExport-Excel -Path $reportPath.Replace('.csv', '.xlsx'). - Testing First: Always test with a non-critical device/collection pair before running in production to validate behavior.
- Error Logging: The CSV report captures every action's status, so you can easily audit successes and failures.
Alternative: WMI-Based Approach (If ConfigMgr Module Isn't Available)
If you can't use the ConfigMgr module (e.g., remote machine without module access), you can use WMI calls to interact with SCCM. Here's a quick snippet to get started:
$siteCode = "XYZ" # Replace with your site code $namespace = "root\SMS\site_$siteCode" # Get old device ResourceID via WMI $oldDevice = Get-WmiObject -Namespace $namespace -Class SMS_R_System -Filter "Name='$oldDeviceName'" # Get collections the device is part of $collections = Get-WmiObject -Namespace $namespace -Class SMS_FullCollectionMembership -Filter "ResourceID='$($oldDevice.ResourceID)'"
You'd then use the SMS_Collection.AddMembershipRule and SMS_Collection.RemoveMembershipRule WMI methods to modify memberships, but the ConfigMgr module approach is cleaner and more maintainable.
内容的提问来源于stack exchange,提问作者Er Reddy

