12 May 2020

Populate VMWare Virtual Systems to a ConfigMgr Collection

During the COVID19 pandemic, one of my projects has been to build a new configuration manager server at our newer production site for optimal performance. During this process, we needed to be able to differentiate what servers were on our disaster recovery VMWare server, and what servers were on the production VMWare server. We quickly learned that some of the virtual servers could not be differentiated. The only solution we came up with was to use PowerShell to connect to each of the VMWare servers and retrieve a list of machines, which would then populate the Configuration Manager collection.

The following script does just what I described above. You will need to create a collection in Configuration Manager and populate all of the parameter fields. The ConfigMgrModule will need the full UNC path to the PowerShell ConfigMgr Module. The name of the module is ConfigurationManager.psd1. You can do a get-childitem to locate where the .PSD1 file is located. The ConfigMgrSiteDescription parameter can be anything. I suggest executing this on your Configuration Manager server if you set it up as a scheduled task. It can also be executed using Orchestrator or Azure Automation.

NOTE: You will need to download and install the VMWare PowerShell module before executing this script. The following cmdlet will install it.

 Find-Module -Name VMWare.PowerCLI | Install-Module -force -AllowClobber  


You can download this script from my GitHub site

 <#  
      .SYNOPSIS  
           Add VMWare systems to specified ConfigMgr collection   
        
      .DESCRIPTION  
           This script will query the VMware server for a list of machines. It will then query Configuration Manager to verify which of those machines are present. Finally, it adds the list of machines to a collection, which is assigned to a specific distribution point.  
        
      .PARAMETER ServerCollection  
           List of servers in Configuration Manager to compare with the list of servers from VMWare.  
        
      .PARAMETER ConfigMgrSiteCode  
           Three letter Configuration Manager site code  
        
      .PARAMETER DistributionPointCollection  
           Name of the collection containing a list of systems on the  
        
      .PARAMETER VMWareServer  
           Name of the VMWare server  
        
      .PARAMETER ConfigMgrModule  
           UNC path including file name of the configuration manager module  
        
      .PARAMETER ConfigMgrServer  
           FQDN of SCCM Server  
        
      .PARAMETER ConfigMgrSiteDescription  
           Description of the ConfigMgr Server  
        
      .NOTES  
           ===========================================================================  
           Created with:    SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.142  
           Created on:      5/11/2020 9:50 AM  
           Created by:      Mick Pletcher  
           Filename:        VMWareConfigMgr.ps1  
           ===========================================================================  
 #>  
 [CmdletBinding()]  
 param  
 (  
      [ValidateNotNullOrEmpty()]  
      [string]$AllServersCollection = '',  
      [ValidateNotNullOrEmpty()]  
      [string]$ConfigMgrSiteCode = '',  
      [ValidateNotNullOrEmpty()]  
      [string]$DistributionPointCollection = '',  
      [ValidateNotNullOrEmpty()]  
      [string]$VMWareServer = '',  
      [ValidateNotNullOrEmpty()]  
      [string]$ConfigMgrModule = '',  
      [ValidateNotNullOrEmpty()]  
      [string]$ConfigMgrServer = '',  
      [ValidateNotNullOrEmpty()]  
      [string]$ConfigMgrSiteDescription = ''  
 )  
   
 #Import PowerCLI module  
 Import-Module -Name VMWare.PowerCLI -ErrorAction SilentlyContinue | Out-Null  
 #Collection ID of the collection containing a list of all servers  
 $CollectionID = (Get-WmiObject -Namespace ("root\SMS\site_" + $ConfigMgrSiteCode) -Query ("select * from SMS_Collection Where SMS_Collection.Name=" + [char]39 + $AllServersCollection + [char]39) -ComputerName PRODCM).MemberClassName  
 #Retrieve the list of all servers  
 $MEMCMServerList = Get-WmiObject -Namespace ("root\SMS\site_" + $ConfigMgrSiteCode) -Query "select * FROM $CollectionID" -ComputerName PRODCM | Sort-Object -Property Name  
 #Establish a connection with teh VMWare server  
 Connect-VIServer -Server $VMWareServer | Out-Null  
 $VerifiedServers = @()  
 #Get the list of servers from the VMWare server that are also in Configuration Manager  
 (Get-VM).Name | Sort-Object | ForEach-Object {  
      If ($_ -in $MEMCMServerList.Name) {  
           $VerifiedServers += $_  
      }  
 }  
 #CollectionID of the collection containing a list of all servers in VMWare  
 $CollectionID = (Get-WmiObject -Namespace ("root\SMS\site_" + $ConfigMgrSiteCode) -Query ("select * from SMS_Collection Where SMS_Collection.Name=" + [char]39 + $DistributionPointCollection + [char]39) -ComputerName PRODCM).MemberClassName  
 #Retrieve list of all servers in VMWare ConfigMgr collection  
 $MEMCMServerList = Get-WmiObject -Namespace ("root\SMS\site_" + $ConfigMgrSiteCode) -Query "select * FROM $CollectionID" -ComputerName PRODCM | Sort-Object -Property Name  
 $MissingSystems = @()  
 #Retrieve the list of servers that are not in the ConfigMgr collection  
 $VerifiedServers | ForEach-Object {  
      If ($_ -notin $MEMCMServerList.Name) {  
           $MissingSystems += $_  
      }  
 }  
 If ($MissingSystems -ne $null) {  
      #Import ConfigMgr PowerShell Module  
      Import-Module -Name $ConfigMgrModule -Force  
      #Map drive to ConfigMgr server  
      New-PSDrive -Name $ConfigMgrSiteCode -PSProvider 'AdminUI.PS.Provider\CMSite' -Root $ConfigMgrServer -Description $ConfigMgrSiteDescription | Out-Null  
      #Change current directory to ConfigMgr mapped drive  
      Set-Location -Path ($ConfigMgrSiteCode + ':')  
      #Add missing systems to the specified collection  
      $MissingSystems | ForEach-Object {  
           Add-CMDeviceCollectionDirectMembershipRule -CollectionName $DistributionPointCollection -ResourceID (Get-CMDevice -Name $_).ResourceID  
      }  
 }  

0 comments:

Post a Comment