{"id":7835,"date":"2020-10-30T13:26:44","date_gmt":"2020-10-30T17:26:44","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=7835"},"modified":"2020-10-30T13:26:49","modified_gmt":"2020-10-30T17:26:49","slug":"finding-zombie-files-with-powershell","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/","title":{"rendered":"Finding Zombie Files with PowerShell"},"content":{"rendered":"\n<p><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"100\" hspace=\"10\" align=\"left\" class=\"wp-image-2529\" style=\"width: 150px;\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png\" alt=\"zombie\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png 849w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie-300x200.png 300w\" sizes=\"auto, (max-width: 150px) 100vw, 150px\" \/>Since this is Halloween weekend in the United States, I thought I'd offer up a PowerShell solution to a scary task - finding zombie files. Ok, maybe these aren't really living dead files, but rather files with a 0-byte length. It is certainly possible that you may intentionally want a 0 length file. But perhaps they are artifacts or accidents that you'd like to clean up. Here's one approach you might take.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Before we dig into this, let me emphasize something. Many of my posts are intended to be educational in nature. I often take a scenario, like finding 0-byte files, as a starting point to teach concepts and techniques. There are almost always multiple ways to achieve a task. My code is never intended to be run in production as-is.  Rather, you should take away <em>how <\/em>I am doing something and <em>why<\/em>. The concepts and techniques are more important than solving the ostensible goal.<\/p><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Using CIM<\/h2>\n\n\n\n<p>For this task, I thought I'd turn to using <strong>Get-CimInstance.<\/strong> You may not be aware of it, but there is a WMI class that you can query to find files on a computer called <em>CIM_Datafile<\/em>. In most situations, and to be honest I'm not sure of one where this wouldn't be the case, all files are registered in the CIM repository. Here's what one of these objects looks like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">Status                : OK\nName                  : c:\\work\\samples\\w.txt\nCaption               : c:\\work\\samples\\w.txt\nDescription           : c:\\work\\samples\\w.txt\nInstallDate           : 10\/9\/2020 3:35:49 PM\nAccessMask            : 18809343\nArchive               : True\nCompressed            : False\nCompressionMethod     : \nCreationClassName     : CIM_LogicalFile\nCreationDate          : 10\/9\/2020 3:35:49 PM\nCSCreationClassName   : Win32_ComputerSystem\nCSName                : PROSPERO\nDrive                 : c:\nEightDotThreeFileName : c:\\work\\samples\\w.txt\nEncrypted             : False\nEncryptionMethod      : \nExtension             : txt\nFileName              : w\nFileSize              : 0\nFileType              : Text Document\nFSCreationClassName   : Win32_FileSystem\nFSName                : NTFS\nHidden                : False\nInUseCount            : \nLastAccessed          : 10\/30\/2020 11:49:34 AM\nLastModified          : 10\/9\/2020 6:56:31 PM\nPath                  : \\work\\samples\\\nReadable              : True\nSystem                : False\nWriteable             : True\nManufacturer          : \nVersion               : \nPSComputerName        : <\/code><\/pre>\n\n\n\n<p>Let's say I want to find all files in C:\\work\\samples that has a file size of 0. I can write a WMI filter like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">\"Drive='c:' AND path = '\\\\work\\\\samples\\\\' AND filesize=0\"<\/code><\/pre>\n\n\n\n<p>When creating WMI\/CIM queries, you need to escape back slashes thus the path value <strong>\\work\\samples\\<\/strong> becomes <strong>\\\\work\\\\samples\\\\<\/strong>. Also remember that the operators in a WMI\/CIM query are the legacy, not PowerShell, operators.<\/p>\n\n\n\n<p>In PowerShell, we stress the importance of filtering early. If a command offers a way to filter, then use it. Early filtering is almost always better than getting everything and then piping to <strong>Where-Object<\/strong>. This is not to imply that using Where -Object is a <em>bad thing<\/em>. Sometimes you have no choice, or intentionally need to pipe to Where-Object. Just be sure you know <strong>why <\/strong>you are using Where-Object.<\/p>\n\n\n\n<p>Here's my simple test.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"234\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1-1024x234.png\" alt=\"\" class=\"wp-image-7837\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1-1024x234.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1-300x68.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1-768x175.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1-1536x350.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1-850x194.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-1.png 1855w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I know that my basic query works and I get the result I expect. Now, I want to take a step back and file all 0-length files in C:\\Work.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Get-CimInstance -ClassName CIM_Datafile -Filter \"Drive='c:' AND path = '\\\\work\\\\' AND filesize=0\" | Select-Object Name,FileSize<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"126\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-1024x126.png\" alt=\"\" class=\"wp-image-7838\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-1024x126.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-300x37.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-768x94.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-1536x189.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-2048x252.png 2048w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-2-850x104.png 850w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hmmm. This query found the file in the root of C:\\Work, but it didn't find the other files. The more specific you can make your WMI queries, typically the faster they run. However, in this case, I need to extend the query a bit by using a wildcard. I want to find files where the path <em>starts <\/em>with \\\\work.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Get-CimInstance -ClassName CIM_Datafile -Filter \"Drive='c:' AND path LIKE '\\\\work\\\\%' AND filesize=0\" | Select-Object Name,FileSize<\/code><\/pre>\n\n\n\n<p>In a WMI\/Cim query, use <strong>% <\/strong>as the wildcard character in place of the traditional <strong>*<\/strong>. Also note that I changed the operator to <strong>LIKE<\/strong>. The operators are not case-sensitive. I used upper-case  so that they would stand out. One significant drawback to this approach is that it is much slower than using \"equal to\" comparisons. But it should eventually work.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"147\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3-1024x147.png\" alt=\"\" class=\"wp-image-7840\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3-1024x147.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3-300x43.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3-768x110.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3-1536x220.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3-850x122.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-3.png 2005w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Caveats and Tips<\/h2>\n\n\n\n<p>When using WMI\/CIM queries there are a few things to keep in mind. First, there's no guarantee that every single object (in this case file) has been registered with the CIM repository. It is theoretically possible that your query will miss files. In this specific use-case, you can always enumerate folders with Get-ChildItem.<\/p>\n\n\n\n<p>As I was working on this, I discovered that if the folder is actually using a reparse point, the query takes considerably longer and might not even work as expected. For example, my C:\\Scripts folder is actually a link to OneDrive.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">PS C:\\> get-item c:\\scripts | Select Target\n\nTarget\n------\n{D:\\OneDrive\\Scripts}\n<\/code><\/pre>\n\n\n\n<p>I found that if I used C:\\Scripts in my query, I got incomplete results. But if I used D:\\OneDrive\\Scripts I got the results I expected much faster.<\/p>\n\n\n\n<p>Another way to speed up the process is to limit the properties that Get-CimInstance needs to get. This is another type of filtering. The first time I searched C:\\Work for 0-byte files it took 8 minutes. But since I only need a few properties, I can refine my command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Get-CimInstance -ClassName CIM_Datafile -Filter \"Drive='c:' AND path LIKE '\\\\work\\\\%' AND filesize=0\" -property Name,FileSize | Select-Object Name,FileSize<\/code><\/pre>\n\n\n\n<p>I got the same results but this time in 39 seconds. I'll admit that large queries can sometimes take a long time and sometimes run faster than you expect. Although as a rule, using LIKE, always slows down the query.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a Function<\/h2>\n\n\n\n<p>With all of this in mind, I put together a function to find 0-byte files in a given path.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function Get-ZeroLengthFiles {\n    [CmdletBinding()]\n    [alias(\"gzf\", \"zombie\")]\n    Param(\n        [Parameter(Position = 0)]\n        [ValidateScript( { Test-Path -Path $_ })]\n        [string]$Path = \".\",\n        [switch]$Recurse\n    )\n    Begin {\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)\"\n        #select a subset of properties which speeds things up\n        $get = \"Name\", \"CreationDate\", \"LastModified\", \"FileSize\"\n\n        $cimParams = @{\n            Classname   = \"CIM_DATAFILE\"\n            Property    = $get\n            ErrorAction = \"Stop\"\n            Filter      = \"\"\n        }\n    } #begin\n    Process {\n         Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Using specified path $Path\"\n         #test if folder is using a link or reparse point\n         if ( (Get-Item -path $Path).Target) {\n             $target =  (Get-Item -path $Path).Target\n            Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] A reparse point was detected pointing towards $target\"\n            #re-define $path to use the target\n            $Path = $Target\n         }\n        #convert the path to a file system path\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Converting $Path\"\n        $cPath = Convert-Path $Path\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Converted to $cPath\"\n\n        #trim off any trailing \\ if cPath is other than a drive root like C:\\\n        if ($cpath.Length -gt 3 -AND $cpath -match \"\\\\$\") {\n            $cpath = $cpath -replace \"\\\\$\", \"\"\n        }\n\n        #parse out the drive\n        $drive = $cpath.Substring(0, 2)\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Using Drive $drive\"\n\n        #get the folder path from the first \\\n        $folder = $cpath.Substring($cpath.IndexOf(\"\\\")).replace(\"\\\", \"\\\\\")\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Using folder $folder (escaped)\"\n\n        if ($folder -match \"\\w+\" -AND $PSBoundParameters.ContainsKey(\"Recurse\")) {\n            #create the filter to use the wildcard for recursing\n            $filter = \"Drive='$drive' AND Path LIKE '$folder\\\\%' AND FileSize=0\"\n        }\n        elseif ($folder -match \"\\w+\") {\n            #create an exact path pattern\n            $filter = \"Drive='$drive' AND Path='$folder\\\\' AND FileSize=0\"\n        }\n        else {\n            #create a root drive filter for a path like C:\\\n            $filter = \"Drive='$drive' AND Path LIKE '\\\\%' AND FileSize=0\"\n        }\n\n        #add the filter to the parameter hashtable\n        $cimParams.filter = $filter\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Looking for zero length files with filter $filter\"\n\n        #initialize a counter to keep track of the number of files found\n        $i=0\n        Try {\n            Write-Host \"Searching for zero length files in $cpath. This might take a few minutes...\" -ForegroundColor magenta\n            #find files matching the query and create a custom object for each\n            Get-CimInstance @cimParams | ForEach-Object {\n                #increment the counter\n                $i++\n\n                #create a custom object\n                [PSCustomObject]@{\n                    PSTypeName   = \"cimZeroLengthFile\"\n                    Path         = $_.Name\n                    Size         = $_.FileSize\n                    Created      = $_.CreationDate\n                    LastModified = $_.LastModified\n                }\n            }\n        }\n        Catch {\n            Write-Warning \"Failed to run query. $($_.exception.message)\"\n        }\n        if ($i -eq 0) {\n            #display a message if no files were found\n            Write-Host \"No zero length files were found in $cpath.\" -ForegroundColor yellow\n        }\n        else {\n             Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Found $i matching files\"\n        }\n    } #process\n    End {\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)\"\n    } #end\n}<\/code><\/pre>\n\n\n\n<p>I hope that the comments explain what I am doing and why. I even added a fun command alias for the season.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"463\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4-1024x463.png\" alt=\"\" class=\"wp-image-7841\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4-1024x463.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4-300x136.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4-768x347.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4-1536x694.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4-850x384.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-4.png 1952w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In the function I'm writing a custom object to the pipeline so that I can use the results in PowerShell.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"164\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-5-1024x164.png\" alt=\"\" class=\"wp-image-7842\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-5-1024x164.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-5-300x48.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-5-768x123.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-5-850x136.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/datatfile-5.png 1413w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I ran the function for C:\\ recursively and it took about 41 seconds to find 1774 files. That seems pretty efficient to me!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>When approaching any task, always start with a simple command that you can run in the console. If you can't run a command successfully from a prompt, you will struggle to write a function or script around it. Even I didn't write the function first. This is especially true when using the CIM cmdlets and trying to come up with an elegant and efficient query.<\/p>\n\n\n\n<p>If you'd like to learn more about PowerShell scripting, consider grabbing a copy of <a href=\"https:\/\/leanpub.com\/powershell-scripting-toolmaking\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">PowerShell Scripting and Toolmaking<\/a>. If you have any questions about what I did or why, please feel free to leave a comment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since this is Halloween weekend in the United States, I thought I&#8217;d offer up a PowerShell solution to a scary task &#8211; finding zombie files. Ok, maybe these aren&#8217;t really living dead files, but rather files with a 0-byte length. It is certainly possible that you may intentionally want a 0 length file. But perhaps&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Boo! Finding Zombie Files with #PowerShell","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[387,224,388,534],"class_list":["post-7835","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-cim","tag-function","tag-get-ciminstance","tag-powershell"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Finding Zombie Files with PowerShell &#8226; The Lonely Administrator<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Finding Zombie Files with PowerShell &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"Since this is Halloween weekend in the United States, I thought I&#039;d offer up a PowerShell solution to a scary task - finding zombie files. Ok, maybe these aren&#039;t really living dead files, but rather files with a 0-byte length. It is certainly possible that you may intentionally want a 0 length file. But perhaps...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2020-10-30T17:26:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-10-30T17:26:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Finding Zombie Files with PowerShell\",\"datePublished\":\"2020-10-30T17:26:44+00:00\",\"dateModified\":\"2020-10-30T17:26:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/\"},\"wordCount\":937,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/zombie.png\",\"keywords\":[\"CIM\",\"Function\",\"Get-CIMInstance\",\"PowerShell\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/\",\"name\":\"Finding Zombie Files with PowerShell &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/zombie.png\",\"datePublished\":\"2020-10-30T17:26:44+00:00\",\"dateModified\":\"2020-10-30T17:26:49+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/zombie.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/zombie.png\",\"width\":\"849\",\"height\":\"566\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7835\\\/finding-zombie-files-with-powershell\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Finding Zombie Files with PowerShell\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Finding Zombie Files with PowerShell &#8226; The Lonely Administrator","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/","og_locale":"en_US","og_type":"article","og_title":"Finding Zombie Files with PowerShell &#8226; The Lonely Administrator","og_description":"Since this is Halloween weekend in the United States, I thought I'd offer up a PowerShell solution to a scary task - finding zombie files. Ok, maybe these aren't really living dead files, but rather files with a 0-byte length. It is certainly possible that you may intentionally want a 0 length file. But perhaps...","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/","og_site_name":"The Lonely Administrator","article_published_time":"2020-10-30T17:26:44+00:00","article_modified_time":"2020-10-30T17:26:49+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Finding Zombie Files with PowerShell","datePublished":"2020-10-30T17:26:44+00:00","dateModified":"2020-10-30T17:26:49+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/"},"wordCount":937,"commentCount":2,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png","keywords":["CIM","Function","Get-CIMInstance","PowerShell"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/","name":"Finding Zombie Files with PowerShell &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png","datePublished":"2020-10-30T17:26:44+00:00","dateModified":"2020-10-30T17:26:49+00:00","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/10\/zombie.png","width":"849","height":"566"},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7835\/finding-zombie-files-with-powershell\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Finding Zombie Files with PowerShell"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":4112,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4112\/scary-powershell\/","url_meta":{"origin":7835,"position":0},"title":"Scary PowerShell","author":"Jeffery Hicks","date":"October 31, 2014","format":false,"excerpt":"In honor of today's festivities, at least in the United States, I thought we'd look at some scary PowerShell. I have seen a lot of scary things in blog posts, tweets and forum discussions. Often these scary things are from people just getting started with PowerShell who simply haven't learned\u2026","rel":"","context":"In &quot;Best Practices&quot;","block_context":{"text":"Best Practices","link":"https:\/\/jdhitsolutions.com\/blog\/category\/best-practices\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2014\/10\/103114_1654_ScaryPowerS1.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1801,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1801\/finding-files-in-the-path-a-pipeline-perk\/","url_meta":{"origin":7835,"position":1},"title":"Finding Files in the Path &#8211; A Pipeline Perk","author":"Jeffery Hicks","date":"November 17, 2011","format":false,"excerpt":"I've been chipping in on a forum post about finding if a given file exists in any folder within the system environmental %PATH% variable using Windows PowerShell. There are several ways you might approach this. But the best way in my opinion is to leverage the PowerShell pipeline. Perhaps you\u2026","rel":"","context":"In &quot;Scripting&quot;","block_context":{"text":"Scripting","link":"https:\/\/jdhitsolutions.com\/blog\/category\/scripting\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6996,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6996\/powershell-controller-scripts\/","url_meta":{"origin":7835,"position":2},"title":"PowerShell Controller Scripts","author":"Jeffery Hicks","date":"November 26, 2019","format":false,"excerpt":"When it comes to PowerShell scripting we tend to focus a lot on functions and modules. We place an emphasis on building re-usable tools. The idea is that we can then use these tools at a PowerShell prompt to achieve a given task. More than likely, these tasks are repetitive.\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":4305,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4305\/what-powershell-script-was-i-working-on\/","url_meta":{"origin":7835,"position":3},"title":"What PowerShell Script Was I Working On?","author":"Jeffery Hicks","date":"March 24, 2015","format":false,"excerpt":"Last week I shared a script for finding recently modified files in a given directory. In fact, it wouldn't be that difficult to find the last files I was working on and open them in the PowerShell ISE. Assuming my Get-RecentFile function is loaded it is a simple as this:\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2673,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/2673\/friday-fun-edit-recent-file\/","url_meta":{"origin":7835,"position":4},"title":"Friday Fun: Edit Recent File","author":"Jeffery Hicks","date":"January 4, 2013","format":false,"excerpt":"As you might imagine I work on a lot of PowerShell projects at the same time. Sometimes I'll start something at the beginning of the week and then need to come back to it at the end of the week. The problem is that I can't always remembered what I\u2026","rel":"","context":"In &quot;Powershell 3.0&quot;","block_context":{"text":"Powershell 3.0","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-3-0\/"},"img":{"alt_text":"Edit-RecentFile","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/01\/Edit-RecentFile-300x209.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1677,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1677\/renaming-files-with-powershell\/","url_meta":{"origin":7835,"position":5},"title":"Renaming Files with PowerShell","author":"Jeffery Hicks","date":"October 12, 2011","format":false,"excerpt":"I am not a big fan of file names with spaces. I realize they are easy to read and obviously much more \"natural\", but they are simply a royal pain to deal with, especially when working from a command prompt or PowerShell. So naturally the solution is to rename these\u2026","rel":"","context":"In &quot;PowerShell v2.0&quot;","block_context":{"text":"PowerShell v2.0","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-v2-0\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/7835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=7835"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/7835\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=7835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=7835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=7835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}