A quicky

Hyper-V clustered hosts. Storage of some VMs migrated from one host to another. On rare occasions migration failed. Reason is now irrelevant. But after this – there are some empty folders left on Clustered Shared Volumes:


───Planned Virtual Machines


───Virtual Hard Disks

└───Virtual Machines

There are also other situation where there are bunch of empty folders left (testing, installations, migrations etc).

I was looking for a neat solution and found this post by Jeffery Hicks – Link.

After a few minutes I’ve got a working function that:

  1. Can query local system
  2. Can query remote system (using Invoke-Command)
  3. Can use Credential parameter for remote sessions
  4. And thanks to the above – works also from PS Core:)

Here’s the code:

function Get-EmptyFolder {
Returns if there are empty folders in given path.
Will check for empty folders in given path. If ComputerName is provided will connect to remote computer. Credential parameter works in combination with ComputerName only
Path to check for empty folders
.PARAMETER ComputerName
Remote computer name
.PARAMETER Credential
Credentials for remote computer
Get-EmptyFolder -path 'c:\AdminTools','C:\Program Files' -ComputerName Server1 -Verbose
VERBOSE: Processing with remote computer {Server1}
VERBOSE: Processing with default credentials of user {mczerniawski_admin}
Directory: C:\AdminTools
Mode LastWriteTime Length Name PSComputerName
—- ————- —— —- ————–
d—– 05.11.2018 14:35 VMs Server1
Get-EmptyFolder -path 'c:\AdminTools','C:\Program Files' -Verbose
VERBOSE: Processing local computer {MyMachine1}
Directory: C:\AdminTools
Mode LastWriteTime Length Name
—- ————- —— —-
d—– 26.11.2018 15:49 1
[Parameter(Mandatory, HelpMessage = 'Path to check', Position = 0,
[Parameter(Mandatory = $false, HelpMessage = 'Provide Computer Name',
[Parameter(Mandatory = $false, HelpMessage = 'Provide Credentials for ComputerName',
begin {
$localExecution = $true
#region PSSession parameters
if ($PSBoundParameters.ContainsKey('ComputerName')) {
$connectionParams = @{
ComputerName = $ComputerName
Write-Verbose -Message "Processing with remote computer {$ComputerName}"
if ($PSBoundParameters.ContainsKey('Credential')) {
$connectionParams.Credential = $Credential
Write-Verbose -Message "Processing with provided credentials {$($Credential.UserName)}"
else {
Write-Verbose -Message "Processing with default credentials of user {$($env:USERNAME)}"
$localExecution = $false
else {
Write-Verbose -Message "Processing local computer {$($env:COMPUTERNAME)}"
process {
if ($localExecution) {
Get-ChildItem -Path $Path | Where-Object -FilterScript {$PSItem.PSIsContainer -eq $True} | Where-Object -FilterScript {-NOT $_.GetFiles("*", "AllDirectories")}
else {
Invoke-Command @connectionParams -ScriptBlock {
Get-ChildItem -Path $USING:Path | Where-Object -FilterScript {$PSItem.PSIsContainer -eq $True} | Where-Object -FilterScript {-NOT $_.GetFiles("*", "AllDirectories")}

view raw


hosted with ❤ by GitHub

And here’s the output:

  • Local run:

  • Remote run with credential parameter

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s