none
Using an IF statement to bypass and empty folder RRS feed

  • Question

  • Hello;

    I'm new to the PowesrShell, I'm using version 1.0 on Windows Server 2003 in a "workgroup" not a Domain.  I want to clean out areas that are acting as temporary folders.  This example is deleting the files in the C:\Documents and Settings\"Username"\My Documents\Groupwise

    My Error conditions I don't believe are working.  

    I'm collecting the list of users in the Variable $User using Get-ChildItem 'C:\Documents and Settings' and this is working.  

    I'm doing a ForEach cmdlet to work my way down through the list of users in the C:\Documents and Settings object.  The Remove-Item code is working but when it finds a user without a Groupwise folder its producing an error.  The script continues through the list and clears the contents for users with a GroupWise folder.  It works but not gracefully.  

    Am I out in left field with my approach ?

    This is my code

    $erroractionpreferences = "SilentlyContinue"
    $error.clear()
    # Get Username
    $User = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($User in $User)
    #IF (Test-Path -Path C:\Documents and Settings\$User"\My Documents\GroupWise")
    {Remove-Item C:\Docume~1\$User"\My Documents\GroupWise\*.*" -Force}

    I tried using the shown "IF" Statement but that doesn't work.  This is the error I get when including the "IF"

    Missing statement body in foreach loop.
    At C:\downloads\powershell_scripts\childitem.ps1:6 char:2
    +      <<<< If (Test-Path -Path C:\Documents and Settings\$User"\My Documents\GroupWise")
        + CategoryInfo          : ParserError: (:) [], ParseException
        + FullyQualifiedErrorId : MissingForeachStatement

    Thanks for your help

    Monday, January 12, 2015 1:35 PM

Answers

  • Instead of coding
    ForEach ($User in $User)
    IF (Test-Path -Path C:\Documents and Settings\$User"\My Documents\GroupWise")
    {Remove-Item C:\Docume~1\$User"\My Documents\GroupWise\*.*" -Force}

    you should code
    ForEach ($U in $User) {
       IF (Test-Path -Path C:\Documents and Settings\$U"\My Documents\GroupWise")
       {Remove-Item C:\Docume~1\$User"\My Documents\GroupWise\*.*" -Force}
    }

    If your aim is to make your script understandable for your successors (instead of confusing them) then you should replace
    # Get Username
    $User = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($User in $User)

    with
    # Get Profile Folder Name
    $Profiles = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($Profile in $Profiles)

    because the items you are looking at are not user accounts but profile folders.

    • Proposed as answer by jrv Monday, January 12, 2015 4:42 PM
    • Marked as answer by Jeep-Silver-Lake Monday, January 12, 2015 7:59 PM
    Monday, January 12, 2015 4:22 PM

All replies

  • Here's a couple things to start with....

    You can't do foreach ($User in $User): change that to $U in $User, then use the $U variable inside the foreach to work with the current user (for that iteration through the loop). If it makes more sense, you could collect the results of your Get-ChildItem cmdlet into $Users and then change your Foreach to foreach ($User in $Users) and then work with $User inside the foreach.

    As well, you should change the Test-Path's -Path parameter value to "C:\Documents and Settings\$User\My Documents\GroupWise". This will do a couple things: One, it will keep the path together (notice it has spaces), and two, it will expand the $User variable so that it's value is entered into the path. Again, you made need to change $User according to the direction you went after reading my first paragraph.

    Monday, January 12, 2015 2:50 PM
  • Instead of coding
    ForEach ($User in $User)
    IF (Test-Path -Path C:\Documents and Settings\$User"\My Documents\GroupWise")
    {Remove-Item C:\Docume~1\$User"\My Documents\GroupWise\*.*" -Force}

    you should code
    ForEach ($U in $User) {
       IF (Test-Path -Path C:\Documents and Settings\$U"\My Documents\GroupWise")
       {Remove-Item C:\Docume~1\$User"\My Documents\GroupWise\*.*" -Force}
    }

    If your aim is to make your script understandable for your successors (instead of confusing them) then you should replace
    # Get Username
    $User = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($User in $User)

    with
    # Get Profile Folder Name
    $Profiles = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($Profile in $Profiles)

    because the items you are looking at are not user accounts but profile folders.

    • Proposed as answer by jrv Monday, January 12, 2015 4:42 PM
    • Marked as answer by Jeep-Silver-Lake Monday, January 12, 2015 7:59 PM
    Monday, January 12, 2015 4:22 PM
  • You do not need to test paths or

    $profilepaths=(Get-ChildItem 'C:\Documents and Settings' -Directory)|%{$_.Fullname}
    ForEach($path in $profilepaths){
        Write-Host $path -fore green
        Remove-Item "$path\GroupWise\*" -Confirm:$false -Verbose -whatif -ea 0
    }

    Or even better:

    Get-ChildItem 'C:\Documents and Settings' -Directory|
        ForEach-Object{
    	$path="$($_.Fullname)\My Documents\GroupWise\*"
            Write-Host $path -fore green
            Remove-Item $path -Confirm:$false -Verbose -whatif -ea 0 
       }
    


    ¯\_(ツ)_/¯

    Monday, January 12, 2015 4:59 PM
  • Mr Frederik Long;

    Could you please clarify your information. I think what you're saying is as follows:

    # Get Profile Folder Name
    $Profiles = Get-ChildItem 'C:\Documents and Settings'

    ForEach ($Profile in $Profile) {

       IF (Test-Path -Path C:\Documents and Settings\$Profile"\My Documents\GroupWise")
       {Remove-Item C:\Docume~1\$Profile"\My Documents\GroupWise\*.*" -Force}
    }

    The variable usage is what is confusing.  Once I set the variable in this example $Profiles, then isn't that what's used in the rest of the script.  The ForEach ($U in $User) is confusing

    You're all very helpful

    Monday, January 12, 2015 6:48 PM
  • Mr. JRV

    Below is the error I get when I run your script.  I'm thinking I need to set a variable $Profile for the Get-Children cmdlet

    $Profile = Get-ChildItem 'C:\Documents and Settings' -Directory|
    Get-ChildItem 'C:\Documents and Settings' -Directory|
        ForEach-Object{
    	$path="$($_.Fullname)\My Documents\GroupWise\*"
            Write-Host $path -fore green
            Remove-Item $path -Confirm:$false -Verbose -whatif -ea 0 
       }

    Get-ChildItem : A parameter cannot be found that matches parameter name 'Direct
    ory'.
    At C:\Downloads\PowerShell_Scripts\GrpFolder2.ps1:1 char:53
    + Get-ChildItem 'C:\Documents and Settings' -Directory <<<< |
        + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterB
       indingException
        + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Comm
       ands.GetChildItemCommand

    Monday, January 12, 2015 7:02 PM
  • I wrote
    ForEach ($Profile in $Profiles) { . . .

    this means that the variable "$Profile" assumes one value after the other that are kept in the collection "$Profiles".  You promptly turned this into
    ForEach ($Profile in $Profile) { . . .

    By omitting the "s" in $Profiles, you made the same error that Tommy Maynard pointed out.


    Monday, January 12, 2015 7:04 PM
  • Get-ChildItem : A parameter cannot be found that matches parameter name 'Direct
    ory'.
    At C:\Downloads\PowerShell_Scripts\GrpFolder2.ps1:1 char:53
    + Get-ChildItem 'C:\Documents and Settings' -Directory <<<< |
        + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterB
       indingException
        + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Comm
       ands.GetChildItemCommand

    You should upgrade to PowerShell V3. XP is obsolete and unsupported.

    This will work in V2:

    Get-ChildItem 'C:\Documents and Settings' |
        Where{$_.PsIsContainer} |
        ForEach-Object{
    	$path="$($_.Fullname)\My Documents\GroupWise\*"
            Write-Host $path -fore green
            Remove-Item $path -Confirm:$false -Verbose -whatif -ea 0 
       }


    ¯\_(ツ)_/¯



    • Edited by jrv Monday, January 12, 2015 7:11 PM
    Monday, January 12, 2015 7:10 PM
  • Ok; I need to understand more on the usage of "s"  within "Profiles" and " Users".  I kind of see the mechanics of it, I'll have to read more on this concept.

    This is the code that is working.  It does error on one "open" powerpoint file that a user has open.  For reason beyond this discussion this user hasn't move the file to a better place then the temporary "Groupwise" folder.  I'm not going to worry about it..  I'll look into error conditions.  I like this code Mr. Long provided and Thank Everyone for their input.

    # Get Profile Folder Name Groupwise
    $Profiles = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($Profile in $Profiles){
       IF (Test-Path -Path "C:\Documents and Settings\$Profile\My Documents\GroupWise")
       {Remove-Item C:\Docume~1\$Profile"\My Documents\GroupWise\*.*" -Force}
    }

    Thanks again.

    Kevin

    Monday, January 12, 2015 7:58 PM
  • Mr. JRV

    Yes; there's a lot that needs upgrading, and we're beginning to.  We're a Automotive manufacturing / supplier we run lean.  Thank You for your help on this matter.  I hope you have a nice day.

    Kevin


    Monday, January 12, 2015 8:03 PM
  • Ok; I need to understand more on the usage of "s"  within "Profiles" and " Users".  I kind of see the mechanics of it, I'll have to read more on this concept.

    The letter "s" is irrelevant. What counts is the variable names. Here is your code again, this time with different variable names:

    $MyFolderCollection = Get-ChildItem 'C:\Documents and Settings'
    ForEach ($Folder in $MyFolderCollection){

    Monday, January 12, 2015 8:59 PM
  • Is this correct ?

    The Variable $MyFolderCollection holds the contents, array or values obtained from the Get-ChildItem cmdlet.

    The Variable $Folder steps through these collected values stored in $MyFoldersCollection.  

    Thanks for the clarification.

    Kevin

    Monday, January 12, 2015 9:08 PM
  • This is correct.
    Monday, January 12, 2015 9:13 PM
  • Yes, that's correct. Here's an example you can run that may help show you what's happening:

    $listOfNumbers = 1,2,3,4,5,6,7,8,9
    
    foreach ($number in $listOfNumbers) {
    
        Write-Output 'Top of foreach'
        Write-Output "The current number is $number"
        Write-Output 'Bottom of foreach'
    
    }



    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    Monday, January 12, 2015 9:15 PM