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