1
Get-ChildItem -recurse | Where {!$_.PSIsContainer -and `
$_.LastWriteTime -lt (get-date).AddDays(-31)} | Remove-Item -whatif

Get-ChildItem -recurse | Where {$_.PSIsContainer -and `
@(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -recurse -whatif

the above Script can work properly, now I want to combine it with the fllowing script into one script:

$path = "<path to file>"
$shell = new-object -comobject "Shell.Application"
$item = $shell.Namespace(0).ParseName("$path")
$item.InvokeVerb("delete")

Here is my combined Script:

Get-ChildItem -recurse | Where {$_.PSIsContainer -and `
@(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
$path = $_.Fullname
$shell = new-object -comobject "Shell.Application"
$item = $shell.Namespace(0).ParseName("$path")
$item.InvokeVerb("delete") -recurse -whatif

but, I always get the error message:

Expressions are only allowed as the first element of a pipeline.
At line:3 char:7

You must provide a value expression on the right-hand side of the '-' operator.
At line:6 char:28

Unexpected token 'recurse' in expression or statement.
At line:6 char:29

Unexpected token '-whatif' in expression or statement.
At line:6 char:37

anyone can help me?

Triumphant
  • 948
  • 1
  • 11
  • 28
  • What is the *full* combined script? –  Jan 03 '13 at 02:16
  • hi, I have posted the combined script. – Triumphant Jan 03 '13 at 02:17
  • Oh yes, that looks very invalid :( It looks like the goal is "do" the 2nd snippet "for each element" in the pipe, yes? If so, see [ForEach](http://stackoverflow.com/questions/4009154/powershell-foreach-piping-confusion) - in short, `.. | ForEach-Object { "2nd script" }` - but also see `foreach`. –  Jan 03 '13 at 02:18
  • could you post the final Script? – Triumphant Jan 03 '13 at 02:30

1 Answers1

2

You need to use the Foreach-Object cmdlet (alias is foreach) in the last part of your pipeline. Also, you don't want to create the Shell.Application object each time in your pipeline:

$shell = new-object -comobject "Shell.Application"
Get-ChildItem -recurse | 
    Where {$_.PSIsContainer -and `
           @(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
    Foreach {
        $item = $shell.Namespace(0).ParseName(($_.Fullname))
        $item.InvokeVerb("delete")
    }

That said, I'm not sure why you just don't use the Remove-Item cmdlet e.g.:

Get-ChildItem . -r | Where {$_.PSIsContainer -and !$(Get-ChildItem $_.fullname)} | 
    Remove-Item -WhatIf

To make this a script, just put the above command in a .ps1 file like so:

-- Contents of DeleteEmptyDirs.ps1 --
param([string]$path, [switch]$whatif)

Get-ChildItem $path -r | Where {$_.PSIsContainer -and !$(Get-ChildItem $_.fullname)} | 
    Remove-Item -WhatIf:$whatif

Then invoke like so:

PS> .\DeleteEmptyDirs c:\temp -WhatIf 
PS> .\DeleteEmptyDirs c:\temp
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • Your Script can work properly, but I always get the Prompt MesssageBox, how can i avoid it? – Triumphant Jan 03 '13 at 02:33
  • Which prompt message box do you get? Try using the `-Force` parameter on the Remove-Item cmdlet. – Keith Hill Jan 03 '13 at 02:36
  • I'm using $item.InvokeVerb("delete"), and the MessageBox is"Are you sure you want to move this folder to the Recyle Bin?" – Triumphant Jan 03 '13 at 02:40
  • 1
    Why don't you use `Remove-Item` and then you won't be prompted? – Keith Hill Jan 03 '13 at 02:40
  • Because I don't want delete them permanently, I probably make mistakes when doing such thing. Later, I can check the Recyle Bin to avoid mistakes. – Triumphant Jan 03 '13 at 02:42
  • Then find your Recycle Bin, right click it and select Properties and see if "Display delete confirmation dialog" is checked, if so, uncheck it and try again. BTW, the point of using the `-WhatIf` parameter on Remove-Item is that it will show you what it is going to delete without actually deleting it. You have to remove the `-WhatIf` parameter to get it to delete the dirs. – Keith Hill Jan 03 '13 at 02:44
  • Oops, this method can actually work as expected, but, I want to control it in the Script. Is it possible? – Triumphant Jan 03 '13 at 02:47