people from different IT team uploaded same iso images file in to different datastore and clusters. Now need to get the info.
Can expert please guide me how to get the list of items of datastore. mainly i need to see location of iso files of different OS which are uploaded to datastorage.
Make sure you are connected to all vCenters.
Then run this
foreach ($vc in $global:DefaultVIServers) {
ForEach-Object -Process {
Get-Datastore -Server $_ -PipelineVariable ds |
ForEach-Object -Process {
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
$report += Get-ChildItem -Path DS:\ISO -Filter *.iso -Recurse |
Select-Object @{N = 'vCenter'; E = { $vc.Name } },
@{N = 'Datastore'; E = { $ds.Name } },
Name, FolderPath
Remove-PSDrive -Name DS -Confirm:$false
}
}
}
$report | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Have a look at Re: how to list files in ISO directory in a particular network attached datastore using VMware vSphe...
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi
in the script, i need to mention datastore name, right that is what i understand.We have approx 22 Vcenter and every vcenter with approx 50 datastorage.
i know that running all vcenter will take approx 1 hrs to get the report. but am exporting it to csv with each vcenter name.
connect-viserver vcenter IP
$datastoreName = 'datastoragename'
$ds = Get-Datastore -Name $datastoreName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
Get-ChildItem -Path DS:\ISO -Filter *.iso -Recurse | Select Name,FolderPath
Remove-PSDrive -Name DS -Confirm:$false
right ??
LucD
its showing blank result
Import-Module VMware.VimAutomation.Vds
Connect-VIServer xxxxxxx -User -Password
$datastoreName = 'datastorename'
$ds = Get-Datastore -Name $datastoreName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
Get-ChildItem -Path DS:\ISO -Filter *.iso -Recurse | Select Name,FolderPath
Remove-PSDrive -Name DS -Confirm:$false | Out-File C:\Windows\addins\iso.html
i have 23 vcenter, in environement
Make sure you are connected to all vCenters.
Then run this
foreach ($vc in $global:DefaultVIServers) {
ForEach-Object -Process {
Get-Datastore -Server $_ -PipelineVariable ds |
ForEach-Object -Process {
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
$report += Get-ChildItem -Path DS:\ISO -Filter *.iso -Recurse |
Select-Object @{N = 'vCenter'; E = { $vc.Name } },
@{N = 'Datastore'; E = { $ds.Name } },
Name, FolderPath
Remove-PSDrive -Name DS -Confirm:$false
}
}
}
$report | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD getting blank output csv file
My bad, I still had a test datastore name in the code.
I corrected the code above, please try again.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello LucD
can you confirm , if this command will not delete anything ?
Remove-PSDrive -Name DS -Confirm:$false
Confirmed.
That just removes the PSProvider drive we created to access the datastore.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The New-PSDrive is slower than your grandmother, at scale.
I wrote this function to use the vCenter Datastore Browser instead, which is vastly faster to find content on Datastores.
Remember, ALWAYS use Get-View if it has the data you need vs. the other Get-vObject cmdlets, as it is much faster. if it is in .ExtensionData, for the object Get-View is your best choice for performance on a large scale. for a small number of objects the performance difference is going to be negligible.
Function global:Browse-DataStore{
<#
.SYNOPSIS
Enumerates Folders and Files on a DataStore
.DESCRIPTION
Enumerates Folders and Files on a DataStore
.PARAMETER Datastore
Datastore Name, View or Object
.PARAMETER Server
vCenter Name, Service Instance, or Object
.EXAMPLE
Browse-DataStore -Datastore "DatastoreName" -Server "vCenterName" -Folder "FolderName"
This retrieves the directory structure and writes to screen as an object
.EXAMPLE
Browse-DataStore -Datastore (Get-Datastore "DatastoreName" -Server "vCenterName") -Folder "FolderName"
.EXAMPLE
Browse-DataStore -Datastore (Get-View ViewType Datastore -Filter @{"name"="DatastoreName"} -Server "vCenterName")
.NOTES
This function to circumvent the need for New-PSdrive to read the files on a Datastore
$vCenter = "vCenterName"
$DataStore = Get-Datastore "DataStoreName" -Server $vCenter
$FolderName = "FolderName"
New-PSDrive -Location $DataStore -Name TargetDS -PSProvider VimDatastore -Root "\" | Out-Null
Get-ChildItem "TargetDS:/$FolderName" -Include * -Recurse | Select Name,@{n="Size";e={$_.Length}},LastWriteTime,DatastoreFullPath
Remove-PSDrive -Name TargetDS
.COMPONENT
PowerShell
PowerCLI
.LINK
#No online help available.
#To see the information on Function Options, type: "get-help about_Comment_Based_Help".
#>
[CmdletBinding()]
[OutputType([Object])]
Param (
[parameter(Mandatory, ValueFromPipeline=$True, HelpMessage="Datastore(s) to Browse.")][Object]$Datastore,
[parameter(Mandatory=$False, ValueFromPipeline=$True, HelpMessage="Folder on Datastore(s) to Browse.")][String]$Folder,
[Parameter(Mandatory=$False, ValueFromPipeline=$True, HelpMessage="vCenter(s) to query.")][Object]$Server = $(IF($Global:DefaultVIServers.Name){$Global:DefaultVIServers}ElseIf($Global:DefaultVIServer.Name){$Global:DefaultVIServer}Else{$NULL}),
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
Begin{
Function Connect-VC{
IF(((!($Global:DefaultVIServer | ?{$_.Name -eq $Server}).IsConnected)) -OR ((!($Global:DefaultVIServers | ?{$_.Name -eq $Server}).IsConnected))){
IF(!($Credential)){$Credential = Get-Credential -UserName $Env:UserName -Message "Enter Password to connect to `r`n vCenter [$Server]"}
$vCenter = ""; $vCenter = Connect-VIServer -Server $Server -Credential $Credential
}Else{
IF((!($Global:DefaultVIServer | ?{$_.Name -eq $Server}).IsConnected)){$vCenter = ""; $vCenter = ($Global:DefaultVIServer | ?{$_.Name -eq $Server})}
IF((!($Global:DefaultVIServers | ?{$_.Name -eq $Server}).IsConnected)){$vCenter = ""; $vCenter = ($Global:DefaultVIServers | ?{$_.Name -eq $Server})}
}
}
IF($Server){
IF($(($Server).GetType().Name) -eq "string"){
#Is String
Connect-VC
}ElseIF($(($Server).GetType().Name) -eq "VIServerImpl"){
#Is Connect-VIServer Object
$AnyvCenterConnected = $False
Foreach($Item in $Server){IF($Item.IsConnected -eq $True){$AnyvCenterConnected = $True}}
IF($AnyvCenterConnected -eq $False){Write-Host -Fore Yellow "No vCenter Connected, quitting..."; Break}
$vCenter = $Server
}ElseIF($(($Server).GetType().Name) -eq "ServiceInstance"){
#Is Get-View ServiceInstance Object
$vCenter = $(($Server).Client.ServiceUrl.Split("/")[2])
Connect-VC
}ElseIF($(($Server).GetType().Name) -eq "Object[]"){
#Is a Collection
$AnyvCenterConnected = $False
Foreach($Item in $Server){IF($Item.IsConnected -eq $True){$AnyvCenterConnected = $True}}
IF($AnyvCenterConnected -eq $False){Write-Host -Fore Yellow "No vCenter Connected, quitting..."; Break}
$vCenter = $Server
}
}
}
Process{
IF($Datastore){
Foreach($DS in $Datastore){
IF($(($DS).GetType().Name) -eq "string"){
#Is String
$DSView = (Get-View -ViewType DataStore -Server $vCenter -Filter @{"name"="$($DS)"})
$DSBrowser = Get-View -ID $(($DSView).Browser) -Server $vCenter
}ElseIF((($DS).GetType().Name) -eq "VmfsDatastoreImpl"){
#Is Get-Datastore Object
$DSView = $DS.ExtensionData
$DSBrowser = Get-View -ID $(($DSView).Browser) -Server $($DS.Uid.Split("@",2).Split(":",2)[1])
}ElseIF($(($DS).GetType().Name) -eq "Datastore"){
#Is Get-View Datastore Object
$DSView = $DS
$DSBrowser = Get-View -ID $($DS.Browser) -Server $($DS.Client.ServiceUrl.Split("/")[2])
}
IF($DSBrowser){
$FileQueryFlags = New-Object VMware.Vim.FileQueryFlags
$FileQueryFlags.FileSize = $true
$FileQueryFlags.FileType = $true
$FileQueryFlags.Modification = $true
$FolderFileInfo = New-Object VMware.Vim.FolderFileInfo
$FolderFileQuery = New-Object VMware.Vim.FolderFileQuery
$DatastoreBrowserSearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$DatastoreBrowserSearchSpec.details = $FileQueryFlags
$DatastoreBrowserSearchSpec.sortFoldersFirst = $true
#$RootPath = "[" + $DSView.Summary.Name + "]"
$RootPath = "[" + $DSView.Name + "]"
If($Folder){$RootPath = $RootPath + " " + $Folder}
$SearchResult = $DSBrowser.SearchDatastoreSubFolders($RootPath, $DatastoreBrowserSearchSpec)
$Report = @()
Foreach ($FolderObject in $SearchResult){
Foreach ($Item in $FolderObject.File){
$File = "" | Select Name, Size, Modified, FullPath
$File.Name = $Item.Path
$File.Size = $Item.Filesize
$File.Modified = $Item.Modification
$File.FullPath = $FolderObject.FolderPath + $File.Name
$Report += $File
}
}
$Report = $Report | Sort Name
Return $Report
}
}
}Else{Write-Host -Fore Yellow "No Datastore(s) provided, quitting..."; Break}
}
End{}
}
LucD and @David_A_Stewart
yes this PS-drive is taking too much time like it took 4 hours for 1 vcenter(17 host-2 Cluster) having 39 datastore.
PiyushAnushri,
Which script that you end up using to get the list of stand-alone.ISO files?
LucD solution was working, even though it takes sometimes and creating temporary DS mapping into each and every ESXi hosts.
The DatastoreBrowser method is faster but somewhat more complex to code than the PSDrive.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
No problem Luc,
The most important here is the result if it is the same and not causing any harm to the system, then it is also good.