Can someone give me a PowerCLI Script to list unregistered VMs in a datacenter by scanning Datastores.
Take a look at Luc's blog post VMX Raiders Revisited | LucD notes.
The script in the blog post will also register the unregistered VM's. If you don't want to register the VM's you have to remove the lines 18, 19 and 20 from the script.
The one you mentioned is scanning cluster wise, I want to scan all the Datastores in a datacenter..can you provide script which do scan entire DC
If you take the script from the original "Raiders" post, see Raiders of the Lost VMX, then you can use the WhatIf switch to only report on the unregistered VMX files.
No need to delete lines from the function.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
You can get all the datastores from the datacenter, and then call the function.
$ds = Get-Datacenter -Name MyDC | Get-Datastore | %{$_.Name}
Register-VMX -dsNames $ds -WhatIf
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
In the script from the original "Raiders of the lost VMX" post you can specify a datacenter as a value for the entityName parameter.
LucD,
I have given Datacenter Name for parameter "entityName" in the Raiders of the Lost VMX, script and run, will it give list of unregister VMs
Also I dont want the VMs to get registered, I just want the list of unregistered VMs, apart from the above modification do we need modification ..
function Register-VMX {
param($entityName =$null,$dsNames = $null,$template = $false,$ignore = $null,$checkNFS = $false,$whatif=$false)
function Get-Usage{
Write-Host "Parameters incorrect" -ForegroundColor red
Write-Host "Register-VMX -entityName -dsNames [,...]"
Write-Host "elab_Legacy"
Write-Host "dsNames : one or more datastorename names (not together with -entityName)"
Write-Host "ignore : names of folders that shouldn't be checked"
Write-Host "template : register guests ($false)or templates ($true) - default : $false"
Write-Host "checkNFS : include NFS datastores - default : $false"
Write-Host "whatif : when $true will only list and not execute - default : $false"
}
if(($entityName -ne $null -and $dsNames -ne $null) -or ($entityName -eq $null -and $dsNames -eq $null)){
Get-Usage
break
}
if($dsNames -eq $null){
switch((Get-Inventory -Name $entityName).GetType().Name.Replace("Wrapper","")){
"Cluster"{
$dsNames = Get-Cluster -Name $entityName | Get-VMHost | Get-Datastore | where {$_.Type -eq "VMFS" -or $checkNFS}
| % {$_.Name}
}
"Datacenter"{
$dsNames = Get-Datacenter -Name $entityName | Get-Datastore | where {$_.Type -eq "VMFS" -or $checkNFS} | %
{$_.Name}
}
"VMHost"{
$dsNames = Get-VMHost -Name $entityName | Get-Datastore | where {$_.Type -eq "VMFS" -or $checkNFS} | % {$_.Name}
}
Default{
Get-Usage
exit
}
}
}
else{
$dsNames = Get-Datastore -Name $dsNames | where {$_.Type -eq "VMFS" -or $checkNFS} | Select -Unique | % {$_.Name}
}
$dsNames = $dsNames | Sort-Object
$pattern = "*.vmx"
if($template){
$pattern = "*.vmtx"
}
foreach($dsName in $dsNames){
Write-Host "Checking " -NoNewline; Write-Host -ForegroundColor red -BackgroundColor yellow $dsName
$ds = Get-Datastore $dsName | Select -Unique | Get-View
$dsBrowser = Get-View $ds.Browser
$dc = Get-View $ds.Parent
while($dc.MoRef.Type -ne "Datacenter"){
$dc = Get-View $dc.Parent
}
$tgtfolder = Get-View $dc.VmFolder
$esx = Get-View $ds.Host[0].Key
$pool = Get-View (Get-View $esx.Parent).ResourcePool
$vms = @()
foreach($vmImpl in $ds.Vm){
$vm = Get-View $vmImpl
$vms += $vm.Config.Files.VmPathName
}
$datastorepath = "[" + $ds.Name + "]"
$searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$searchspec.MatchPattern = $pattern
$taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec)
$task = Get-View $taskMoRef
while ("running","queued" -contains $task.Info.State){
$task.UpdateViewData("Info.State")
}
$task.UpdateViewData("Info.Result")
foreach ($folder in $task.Info.Result){
if(!($ignore -and (&{$res = $false; $folder.FolderPath.Split("]")[1].Trim(" /").Split("/") | %{$res = $res -or ($ignore
-contains $_)}; $res}))){
$found = $FALSE
if($folder.file -ne $null){
foreach($vmx in $vms){
if(($folder.FolderPath + $folder.File[0].Path) -eq $vmx){
$found = $TRUE
}
}
if (-not $found){
if($folder.FolderPath[-1] -ne "/"){$folder.FolderPath += "/"}
$vmx = $folder.FolderPath + $folder.File[0].Path
if($template){
$params = @($vmx,$null,$true,$null,$esx.MoRef)
}
else{
$params = @($vmx,$null,$false,$pool.MoRef,$null)
}
if(!$whatif){
$taskMoRef = $tgtfolder.GetType().GetMethod("RegisterVM_Task").Invoke($tgtfolder,
$params)
Write-Host "`t" $vmx "registered"
}
else{
Write-Host "`t" $vmx "registered" -NoNewline; Write-Host -ForegroundColor blue -
BackgroundColor white " ==> What If"
}
}
}
}
}
Write-Host "Done"
}
}
# Register-VMX -entityName "MyDatacenter"
# Register-VMX -dsNames "datastore1","datastore2"
# Register-VMX -dsNames "datastore1","datastore2" -template:$true
# Register-VMX -entityName "MyDatacenter" -ignore "SomeFolder"
# Register-VMX -dsNames "datastore3","datastore4" -ignore "SomeFolder" -checkNFS:$true
# Register-VMX -entityName "MyDatacenter" -whatif:$true
I have given datacneter name for entityName as mentioned above, its been highlighted too in the script. Now will the above script gives the list of unregisterd VMs after running.
You will have to uncomment that line.
Register-VMX -entityName "MyDatacenter" -WhatIf
Btw, what is this line doing in the function ?
Write-Host "elab_Legacy"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Oh ok, I thought Script will take input from Write-Host cmdlet, I have uncommented line Register-VMX -entityName...LucD I dont want the VMs to be registered back to vcenter, I just want the list of Unregistered VMs so will the below script do the same need.
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
Make sure to add the WhatIf switch (see my previous answer).
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks LucD i got what you mentioned, thanks for such a detail explanation.
You're welcome.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD can you help me in taking the output to a text file, because we have lot of datastores in the Dataceneter. It will take lot of time to look at the output of the script.
Not 100% sure I get the question, but if you just want to save the output in a file, one of the ways of doing that could be
Start-Transcript C:\report.txt
Register-VMX -entityName "MyDatacenter" -WhatIf
Stop-Transcript
The reason is use the Transcript cmdlet, is because the function uses the Write-Host cmdlet which writes directly to the screen.
The output of Write-Host can not be redirected or piped to one of the Out- cmdlets.
I know, this is one of my early scripts, when I didn't know or followed several of the PowerShell best practices :smileygrin:
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference