I'm trying to write a PowerShell script which goes through a list of values which are folder or file paths, and delete the files first, then remove the empty folders.
My script so far:
[xml]$XmlDocument = Get-Content -Path h:\List_Files.resp.xml
$Files = XmlDocument.OUTPUT.databrowse_BrowseResponse.browseResult.dataResultSet.Path
Now I'm trying to test each line in the variable to see if it's a file and delete it first, and then go through and remove subfolders and folders. This is just so that it's a clean process.
I can't quite get this next bit to work, but I think I need something like:
foreach ($file in $Files)
{
if (! $_.PSIsContainer)
{
Remove-Item $_.FullName}
}
}
The next section can clean up the subfolders and folders.
Any suggestions?
I found a workaround for this question: use Test-Path
cmdlet with the parameter -FileType
equal to Leaf
for checking if it is a file or Container
for checking if it is a folder:
# Check if file (works with files with and without extension)
Test-Path -Path 'C:\Demo\FileWithExtension.txt' -PathType Leaf
Test-Path -Path 'C:\Demo\FileWithoutExtension' -PathType Leaf
# Check if folder
Test-Path -Path 'C:\Demo' -PathType Container
I originally found the solution here . And the official reference is here .
I think that your $Files
object is an array of strings:
PS D:\PShell> $Files | ForEach-Object {"{0} {1}" -f $_.Gettype(), $_}
System.String D:\PShell\SO
System.String D:\PShell\SU
System.String D:\PShell\test with spaces
System.String D:\PShell\tests
System.String D:\PShell\addF7.ps1
System.String D:\PShell\cliparser.ps1
Unfortunately, the PSIsContainer
property cannot be found on a string object but on a filesystem object, eg
PS D:\PShell> Get-ChildItem | ForEach-Object {"{0} {1}" -f $_.Gettype(), $_}
System.IO.DirectoryInfo SO
System.IO.DirectoryInfo SU
System.IO.DirectoryInfo test with spaces
System.IO.DirectoryInfo tests
System.IO.FileInfo addF7.ps1
System.IO.FileInfo cliparser.ps1
To get a filesystem object from a string:
PS D:\PShell> $Files | ForEach-Object {"{0} {1}" -f (Get-Item $_).Gettype(), $_}
System.IO.DirectoryInfo D:\PShell\SO
System.IO.DirectoryInfo D:\PShell\SU
System.IO.DirectoryInfo D:\PShell\test with spaces
System.IO.DirectoryInfo D:\PShell\tests
System.IO.FileInfo D:\PShell\addF7.ps1
System.IO.FileInfo D:\PShell\cliparser.ps1
Try next code snippet:
$Files | ForEach-Object
{
$file = Get-Item $_ ### string to a filesystem object
if ( -not $file.PSIsContainer)
{
Remove-Item $file}
}
}
We can use get-item
command and supply the path. Then you can check PSIsContainer
(boolean) property that would determine whether the supplied path targets a folder or a file. eg
$target = get-item "C:\somefolder" # or "C:\somefolder\somefile.txt"
if($target.PSIsContainer) {
# it's a folder
}
else { #its a file }
Hope this helps any future visitors.
Consider the following code:
$Files = Get-ChildItem -Path $env:Temp
foreach ($file in $Files)
{
$_.FullName
}
$Files | ForEach {
$_.FullName
}
The first foreach is a PowerShell language command for looping, and the second ForEach is an alias for the ForEach-Object
cmdlet which is something completely different.
In the ForEach-Object
, the $_
points to the current object in the loop, as piped in from the $Files
collection, but in the first foreach, $_
has no meaning.
In the foreach loop use the loop variable $file
:
foreach ($file in $Files)
{
$file.FullName
}
Yet another way is by using DirectoryInfo
.
MWE from the file-name:
$(Get-Item c:\windows\system32) -is [System.IO.DirectoryInfo]
The comment (which I can't comment on) which says: "this is a totally disaster answer, "Container" and "Leaf" worries about regkeys not being dir or file,:. – TechDogLover OR kiaNasirzadeh Nov 12: 2021 at 16,49" is wrong. The official documentation from Microsoft makes it clear that "-PathType Container" is. "An element that contains other elements, such as a directory or registry key." Note the "OR".
So the answer from Alicia is NOT a DISASTER of an answer and is perfectly acceptable for the original poster's question. In fact the only disaster is the comment from TechDogLover OR kiaNasirzadeh.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.