Thursday, June 4, 2020

PS | Script to detect and delete the Orphaned Files

Hi Guys,

Someone recently asked about the script which can detect the orphaned files in a datastore and can remove it with full control and condition was, it should not show the files which are not modified since last x number of days rather it should show the files which are not connected with any VM.

I did little effort and could find that such task is already done brilliantly by someone on Internet.

What I tested -

I removed one vmdk file from VM and then ran the script it exactly shows the vmdk which I removed and then run the command to delete it but it tried to delete entire folder. Go through below line, it will be clear.

Below is the script-

#Start here
function Remove-OrphanedData {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[PSObject[]]$Datastore,
[switch]$Delete
)
begin{
$fldList = @{}
$hdList = @{}
$fileMgr = Get-View FileManager
}
process{
foreach($ds in $Datastore){
if($ds.GetType().Name -eq "String"){
$ds = Get-Datastore -Name $ds
}
if($ds.Type -eq "VMFS" -and $ds.ExtensionData.Summary.MultipleHostAccess){
Get-VM -Datastore $ds | %{
$_.Extensiondata.LayoutEx.File | where{"diskDescriptor","diskExtent" -contains $_.Type} | %{
$fldList[$_.Name.Split('/')[0]] = $_.Name
$hdList[$_.Name] = $_.Name
}
}
Get-Template | where {$_.DatastoreIdList -contains $ds.Id} | %{
$_.Extensiondata.LayoutEx.File | where{"diskDescriptor","diskExtent" -contains $_.Type} | %{
$fldList[$_.Name.Split('/')[0]] = $_.Name
$hdList[$_.Name] = $_.Name
}
}
$dc = $ds.Datacenter.Extensiondata
$flags = New-Object VMware.Vim.FileQueryFlags
$flags.FileSize = $true
$flags.FileType = $true
$disk = New-Object VMware.Vim.VmDiskFileQuery
$disk.details = New-Object VMware.Vim.VmDiskFileQueryFlags
$disk.details.capacityKb = $true
$disk.details.diskExtents = $true
$disk.details.diskType = $true
$disk.details.thin = $true
$searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$searchSpec.details = $flags
$searchSpec.Query += $disk
$searchSpec.sortFoldersFirst = $true
$dsBrowser = Get-View $ds.ExtensionData.browser
$rootPath = "[" + $ds.Name + "]"
$searchResult = $dsBrowser.SearchDatastoreSubFolders($rootPath, $searchSpec)
foreach($folder in $searchResult){
if($fldList.ContainsKey($folder.FolderPath.TrimEnd('/'))){
foreach ($file in $folder.File){
if(!$hdList.ContainsKey($folder.FolderPath + $file.Path)){
New-Object PSObject -Property @{
Folder = $folder.FolderPath
Name = $file.Path
Size = $file.FileSize
CapacityKB = $file.CapacityKb
Thin = $file.Thin
Extents = [string]::Join(',',($file.DiskExtents))
}
if($Delete){
If ($PSCmdlet.ShouldProcess(($folder.FolderPath + " " + $file.Path),"Remove VMDK")){
$dsBrowser.DeleteFile($folder.FolderPath + $file.Path)
}
}
}
}
}
elseif($folder.File | where {"cos.vmdk","esxconsole.vmdk" -notcontains $_.Path}){
$folder.File | %{
New-Object PSObject -Property @{
Folder = $folder.FolderPath
Name = $_.Path
Size = $_.FileSize
CapacityKB = $_.CapacityKB
Thin = $_.Thin
Extents = [String]::Join(',',($_.DiskExtents))
}
}
if($Delete){
if($folder.FolderPath -eq $rootPath){
$folder.File | %{
If ($PSCmdlet.ShouldProcess(($folder.FolderPath + " " + $_.Path),"Remove VMDK")){
$dsBrowser.DeleteFile($folder.FolderPath + $_.Path)
}
}
}
else{
If ($PSCmdlet.ShouldProcess($folder.FolderPath,"Remove Folder")){
$fileMgr.DeleteDatastoreFile($folder.FolderPath,$dc.MoRef)
}
}
}
}
}
}
}
}
}
Remove-OrphanedData -datastore Name_of_datastore


#It will give you below kind of output


Now, if you want to delete this then use below command

Remove-OrphanedData -datastore Name_of_datastore -delete

But before deleting it, let's see what it will be delete. See below pic. I have added a switch -whatif in last after -delete switch.


It will delete entire folder not only single file.

Now, It is up to you that whether you want to remove the entire folder by adding only -delete switch or if you want to delete only vmdk file not entire folder and that will be manual action.

In my case, deletion gave error while deleting the entire folder, might be due to in-use vmx file or so...

Any doubt, let's discuss.

That's it for now. Enjoy the learning!




Thank you,
vCloudNotes


2 comments:

  1. I actually use this script myself. The only issue I have with it is that it doesn't detect if the file is in use by a template published in a content library. Trying to figure out how to add this capability or find an upgraded version with it already.

    ReplyDelete
    Replies
    1. I believe this script will not show the file which is being used by template. Can you share with the example and with snippet like, this file is in use by this template but still this script detects that it is not in use.

      Thank you for your comment.

      Delete

Sponsor

AD BANNER
Powered by Blogger.
The Magazine

Text Widget

Facebook

Extra Ads

AD BANNER

Welcome to my Notes!

Hello Folks, My name is Gautam Johar. Actively working on VMware Cloud and keen to learn new and latest cloud technologies in market. Love ...

Contact Form

Name

Email *

Message *

Followers



Labels

Translate

Breaking

Random Posts

Follow Us

On Linkedin

Recent Posts

Recent Comments

Header Ads

Popular Posts

Popular Posts

Recent Posts

Text Widget

Search This Blog

Copyright © test blog | Powered by Blogger
Design by Saeed Salam | Blogger Theme by NewBloggerThemes.com