VMware Cloud Community
piyushranusri
Enthusiast
Enthusiast
Jump to solution

List Items from Datastore

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.

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Make sure you are connected to all vCenters.
Then run this

$report = @()

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

View solution in original post

13 Replies
piyushranusri
Enthusiast
Enthusiast
Jump to solution

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 ??

Reply
0 Kudos
piyushranusri
Enthusiast
Enthusiast
Jump to solution

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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Make sure you are connected to all vCenters.
Then run this

$report = @()

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

piyushranusri
Enthusiast
Enthusiast
Jump to solution

LucD getting blank output csv file

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
piyushranusri
Enthusiast
Enthusiast
Jump to solution

Hello LucD
can you confirm , if this command will not delete anything ?
Remove-PSDrive -Name DS -Confirm:$false

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Confirmed.
That just removes the PSProvider drive we created to access the datastore.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
David_A_Stewart
Contributor
Contributor
Jump to solution

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{}

}

piyushranusri
Enthusiast
Enthusiast
Jump to solution

LucD​ and @

AlbertWT
Virtuoso
Virtuoso
Jump to solution

PiyushA​nushri,

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.

/* Please feel free to provide any comments or input you may have. */
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The DatastoreBrowser method is faster but somewhat more complex to code than the PSDrive.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

AlbertWT
Virtuoso
Virtuoso
Jump to solution

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.

/* Please feel free to provide any comments or input you may have. */
Reply
0 Kudos