How to search for all VMX files in all datastores and register them into VC ?
001 | function Register-VMX {
|
002 | param($entityName =
$null,$dsNames
= $null,$template
= $false,$ignore
= $null,$checkNFS
= $false,$whatif=$false)
|
003 | |
004 | function Get-Usage{
|
005 | Write-Host "Parameters incorrect" -ForegroundColor red |
006 | Write-Host "Register-VMX -entityName -dsNames
[,...]" |
007 | Write-Host "entityName : a cluster-, datacenter or ESX hostname
(not together with -dsNames)" |
008 | Write-Host "dsNames : one or more datastorename names (not
together with -entityName)" |
009 | Write-Host "ignore : names of folders that shouldn't be
checked" |
010 | Write-Host "template : register guests ($false)or templates
($true) - default : $false" |
011 | Write-Host "checkNFS : include NFS datastores - default :
$false" |
012 | Write-Host "whatif : when $true will only list and not
execute - default : $false" |
013 | }
|
014 | |
015 | if(($entityName -ne $null -and $dsNames -ne $null)
-or ($entityName -eq $null -and $dsNames -eq $null)){
|
016 | Get-Usage |
017 | break |
018 | }
|
019 | |
020 | if($dsNames -eq $null){
|
021 | switch((Get-Inventory -Name $entityName).GetType().Name.Replace("Wrapper","")){ |
022 | "Cluster"{
|
023 | $dsNames =
Get-Cluster -Name $entityName |
Get-VMHost | Get-Datastore |
where {$_.Type
-eq "VMFS" -or $checkNFS} | %
{$_.Name} |
024 | } |
025 | "Datacenter"{
|
026 | $dsNames =
Get-Datacenter -Name $entityName |
Get-Datastore | where
{$_.Type -eq "VMFS" -or $checkNFS} | %
{$_.Name} |
027 | } |
028 | "VMHost"{
|
029 | $dsNames =
Get-VMHost -Name $entityName |
Get-Datastore | where
{$_.Type -eq "VMFS" -or $checkNFS} | %
{$_.Name} |
030 | } |
031 | Default{ |
032 | Get-Usage |
033 | exit |
034 | } |
035 | }
|
036 | }
|
037 | else{ |
038 | $dsNames =
Get-Datastore -Name $dsNames |
where {$_.Type
-eq "VMFS" -or $checkNFS} |
Select -Unique | %
{$_.Name} |
039 | }
|
040 | |
041 | $dsNames =
$dsNames | Sort-Object |
042 | $pattern =
"*.vmx" |
043 | if($template){
|
044 | $pattern =
"*.vmtx" |
045 | }
|
046 | |
047 | foreach($dsName
in $dsNames){
|
048 | Write-Host "Checking " -NoNewline;
Write-Host -ForegroundColor red -BackgroundColor yellow $dsName |
049 | $ds =
Get-Datastore $dsName |
Select -Unique |
Get-View |
050 | $dsBrowser =
Get-View $ds.Browser
|
051 | $dc =
Get-View $ds.Parent
|
052 | while($dc.MoRef.Type -ne "Datacenter"){
|
053 | $dc =
Get-View $dc.Parent
|
054 | }
|
055 | $tgtfolder =
Get-View $dc.VmFolder
|
056 | $esx =
Get-View $ds.Host[0].Key
|
057 | $pool =
Get-View (Get-View $esx.Parent).ResourcePool
|
058 | |
059 | $vms = @()
|
060 | foreach($vmImpl
in $ds.Vm){
|
061 | $vm =
Get-View $vmImpl |
062 | $vms +=
$vm.Config.Files.VmPathName
|
063 | }
|
064 | $datastorepath =
"[" + $ds.Name + "]" |
065 | |
066 | $searchspec =
New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
|
067 | $searchspec.MatchPattern = $pattern |
068 | |
069 | $taskMoRef =
$dsBrowser.SearchDatastoreSubFolders_Task($datastorePath,
$searchSpec) |
070 | |
071 | $task =
Get-View $taskMoRef |
072 | while ("running","queued"
-contains $task.Info.State){ |
073 | $task.UpdateViewData("Info.State")
|
074 | }
|
075 | $task.UpdateViewData("Info.Result")
|
076 | foreach ($folder
in $task.Info.Result){ |
077 | if(!($ignore -and (&{$res =
$false; $folder.FolderPath.Split("]")[1].Trim("
/").Split("/") |
%{$res = $res
-or ($ignore
-contains $_)}; $res}))){
|
078 | $found =
$FALSE |
079 | if($folder.file
-ne $null){
|
080 | foreach($vmx
in $vms){
|
081 | if(($folder.FolderPath + $folder.File[0].Path) -eq $vmx){
|
082 | $found =
$TRUE |
083 | } |
084 | } |
085 | if (-not
$found){
|
086 | if($folder.FolderPath[-1] -ne "/"){$folder.FolderPath += "/"}
|
087 | $vmx =
$folder.FolderPath + $folder.File[0].Path |
088 | if($template){
|
089 | $params =
@($vmx,$null,$true,$null,$esx.MoRef) |
090 | } |
091 | else{ |
092 | $params =
@($vmx,$null,$false,$pool.MoRef,$null)
|
093 | } |
094 | if(!$whatif){
|
095 | $taskMoRef =
$tgtfolder.GetType().GetMethod("RegisterVM_Task").Invoke($tgtfolder,
$params) |
096 | Write-Host "`t" $vmx
"registered" |
097 | } |
098 | else{ |
099 | Write-Host "`t" $vmx
"registered" -NoNewline;
Write-Host -ForegroundColor blue -BackgroundColor white " ==>
What If" |
100 | } |
101 | } |
102 | } |
103 | } |
104 | }
|
105 | Write-Host "Done" |
106 | }
|
107 | }
|
108 | |
109 | # Register-VMX -entityName
"MyDatacenter" |
110 | # Register-VMX -dsNames
"datastore1","datastore2" |
111 | # Register-VMX -dsNames
"datastore1","datastore2" -template:$true
|
112 | # Register-VMX -entityName
"MyDatacenter" -ignore "SomeFolder" |
113 | # Register-VMX -dsNames
"datastore3","datastore4" -ignore "SomeFolder" -checkNFS:$true
|
114 | # Register-VMX -entityName
"MyDatacenter" -whatif:$true |
Annotations
Line 15: both parameters (entityName and dsNames) can not be used together.
Line 20-36: if an entityName was given the switch will retrieve the list of datastores.
Line 37-39: if dsNames was used add or remove NFS datastores (depending on the checkNFS switch)
Line 42-67: retrieval of the required parameters for the SearchDatastoreSubFolders_Task and RegisterVM_Task methods
Line 56: if the datastore is shared between several ESX/ESXi servers, the script will take the first server
Line 67-69: the VMConfigFileQuery seems to have a problem finding VMX files on some datastores. That’s why the script uses the MatchPattern property.
Line 71-74: this loop waits for the SearchDatastoreSubFolders_Task to finish. To make sure it looks at the actual value of the Result property, the script calls the UpdateViewData method.
Line 77: this line takes care of folders that should be ignored. Update 5: for nested folders, the script checks each folderpath qualifier against the -ignore parameter.
Line 86: when you’re connected to an ESX/ESXi host the FolderPath property doesn’t have a forward slash as the last character. This line corrects that.
Line 88-93: the RegisterVM_Task method needs different parameters if it is called for a guest or for a template
Line 88 & 91: the RegisterVM_Task method should use the DisplayName field from the VMX file for the name of the VM that will be registered. Unfortunately you can’t pass a $null value for a parameter that is defined as a String. This bypasses that limitation.
Line 94-100: these lines take care of the -whatif switch
Line 109-114: some sample calls to the Register-VMX function
Usage
The function Register-VMX can be called as follows
- With the -entityName parameter, where you can pass a datacentername, a
clustername or an ESX hostname
- Register-VMX -entityName “MyCluster”
- Register-VMX -entityName “MyDatacenter”
- Register-VMX -entityName “esx1.test.local”
- With the -dsNames parameter, where you can pass one or more datastorenames.
- Register-VMX -dsNames “datastore1″
- Register-VMX -dsNames “datastore1″,”datastore2″,”datastore3″
- With the -template parameter which allows you to specify if you want to
register guests ($false) or templates ($true). The default is to register
guests.
- Register-VMX -dsNames “datastore1″,”datastore2″,”datastore3″ -template:$true
- Register-VMX -entityName “MyCluster” -template:$false
- With the -ignore parameter which allows you to specify that scripts should
not look in specific folders for unregistered VMX files. The default is to look
in all folders.
- Register-VMX -entityName “MyCluster” -ignore “Folder1″,”Folder2″
- With the -checkNFS switch which allows you to specify if NFS datastores
should be checked as well. The default is to not check NFS datastores.
- Register-VMX -entityName “MyCluster” -CheckNFS:$true
- Register-VMX -dsNames “datastore1″,”datastore2″,”datastore3″ -CheckNFS:$true
- With the -whatif switch set to $true the script will only show the actions
and not actually execute them. The default is $false, which means the found .VMX
(or .VMTX) files will be registered.
- Register-VMX -entityName “MyCluster” -whatif:$true


Comments
Post a Comment