none
$Count not counting! in script to delete files from SharePoint library

    Question

  • Hi All - 

          I'm trying to delete files from a test library on a dev server with a limit so that a few files remain. The problem is the limit based on the count does not work and all files in the library are deleted. What am I missing?

    $web = Get-SPWeb -Identity "http://theirIntranet/mainlibrary"
    $docLib = $web.GetList("http://theirIntranet/mainlibrary/TEMP_1")
    $collFiles = $web.GetFolder($docLib).Files
    
    $count = $collFiles.Count
    while ($count-gt 84)
    {
    	$file = $collFiles[$count-1].Item
    	foreach ($file in $collFiles) 
        {
    	Write-Host("DELETED FILE: " + $file.name)
    	$docLib.Items.DeleteItemById($file.Item.ID)
    	}
    }
    $web.Dispose
    Help is much appreciated!


    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    Thursday, June 07, 2012 6:33 AM

Answers

  • Good point, I cut and pasted your code above but restored the actual names for the $web and $docLib variables.

    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    It sounds like the loop initializer is re-evaluating the the obejct on every lop.  Is it possible the the 'Files' collection is dynamic.  If you delete a file does the 'Files.Count'  property automatically decrement.  If so ther is a much easier way to do this.

    foreach($file in  $web.GetFolder($docLib).Files){
        if( $web.GetFolder($docLib).Files.Count -le 84){break}
        $docLib.Items.DeleteItemById($file.Item.ID)
    }

    Somehow I do not think this is the best waay to do this.  I cannot set up a test sharepoint library at this time but I think we can just delete teh items directly once we have a reference to teh item.  The count should then be dynamic so a very simple loop could be obtained.  The same would be try of moving items. Items can also be easily filtered by almost any criteria,


    ¯\_(ツ)_/¯

    • Marked as answer by sqlsolver Friday, June 08, 2012 2:16 AM
    Thursday, June 07, 2012 1:34 PM

All replies

  • It's not clear what you're trying to do using two loops.  The statement:

    $file = $collFiles[$count-1].Item

    is useless, because you overwrite this variable with your foreach loop.  You only need a single loop, and you must decide between a for loop or a foreach loop.

    The reason $count isn't incremented is because you are not incrementing it, or using it for that matter.

    Please explain what you are trying to achieve.


    Grant Ward, a.k.a. Bigteddy

    Thursday, June 07, 2012 6:47 AM
  • To add to Teddy, if you want to increment or subtract from your $count variable you can use the following code:

    $count--
    $count++

    The former will subtract one from the $count variable and the latter will add one to the $count variable.


    Jaap Brasser
    http://www.jaapbrasser.com

    Thursday, June 07, 2012 6:52 AM
  • I'm trying to use the $count to set the number of files to leave in the library, so if $count is -gt 84, I want 84 files untouched. If for instance the library started with a hundred files, I want to delete 16.


    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    Thursday, June 07, 2012 7:00 AM
  • Which files would you like to have removed, the oldest, the newest, end or start of alphabet. Or do you have no preference for which files will be deleted?

    Jaap Brasser
    http://www.jaapbrasser.com

    Thursday, June 07, 2012 7:11 AM
  • The following deletes files until there are only 84 files left which is what it looks like teh code is trying to do.  There is no control over what gets deleted.  Sorting the collection by something like date can control this.

    $web = Get-SPWeb -Identity "http://theirIntranet/mainlibrary"
    $docLib = $web.GetList("http://theirIntranet/mainlibrary/TEMP_1")
    #
    $colFiles=$web.GetFolder($docLib).Files
    for($i=($web.GetFolder($docLib).Files.Count - 84); $i -gt 0; $i--){
         $file=$colFiles[$i]
         Write-Host("DELETED FILE:$($file.name)")
         $docLib.Items.DeleteItemById($file.Item.ID)
    }
    #
    $web.Dispose()
    Note that a 'for' loop handles all conditions.  If the total number of files is less tham 84 to begin with then the loop is skipped. No amount of logic can do this any better than a well designed 'for' loop initializer.


    ¯\_(ツ)_/¯


    • Edited by jrv Thursday, June 07, 2012 7:14 AM
    Thursday, June 07, 2012 7:12 AM
  • That combination brings back:

    Exception calling "DeleteItemById" with "1" argument(s): "Value does not fall within the expected range."

    At C:\Users\rmaxwell\DelDocs2.ps1:13 char:30

    + $docLib.Items.DeleteItemById <<<< ($file.Item.ID)

    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : DotNetMethodException

    so is there perhaps one more adjustment to make? There are 87 documents currently in TEST_1.


    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    Thursday, June 07, 2012 7:50 AM
  • No preference for this test library, but the next script is to move files to a specific library based on their metadata. New files are routed when uploaded via a custom content type. I have to move files that were in the original library to the new divisional libraries with the requirement that their tags stay intact.

    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    Thursday, June 07, 2012 8:21 AM
  • That combination brings back:

    Exception calling "DeleteItemById" with "1" argument(s): "Value does not fall within the expected range."

    At C:\Users\rmaxwell\DelDocs2.ps1:13 char:30

    + $docLib.Items.DeleteItemById <<<< ($file.Item.ID)

    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : DotNetMethodException

    so is there perhaps one more adjustment to make? There are 87 documents currently in TEST_1.


    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    What code are you using that caused this.  Jsut saying that you have an error does not tell us what you did.


    ¯\_(ツ)_/¯

    Thursday, June 07, 2012 8:34 AM
  • Good point, I cut and pasted your code above but restored the actual names for the $web and $docLib variables.

    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    Thursday, June 07, 2012 8:39 AM
  •  No amount of logic can do this any better than a well designed 'for' loop initializer.


    ¯\_(ツ)_/¯


    I like for loops.  There is a place for them still.

    Grant Ward, a.k.a. Bigteddy

    Thursday, June 07, 2012 11:30 AM
  • Especially Fruit Loops, Strange Loops and SST Loops!


    ¯\_(ツ)_/¯

    Thursday, June 07, 2012 1:21 PM
  • Good point, I cut and pasted your code above but restored the actual names for the $web and $docLib variables.

    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    It sounds like the loop initializer is re-evaluating the the obejct on every lop.  Is it possible the the 'Files' collection is dynamic.  If you delete a file does the 'Files.Count'  property automatically decrement.  If so ther is a much easier way to do this.

    foreach($file in  $web.GetFolder($docLib).Files){
        if( $web.GetFolder($docLib).Files.Count -le 84){break}
        $docLib.Items.DeleteItemById($file.Item.ID)
    }

    Somehow I do not think this is the best waay to do this.  I cannot set up a test sharepoint library at this time but I think we can just delete teh items directly once we have a reference to teh item.  The count should then be dynamic so a very simple loop could be obtained.  The same would be try of moving items. Items can also be easily filtered by almost any criteria,


    ¯\_(ツ)_/¯

    • Marked as answer by sqlsolver Friday, June 08, 2012 2:16 AM
    Thursday, June 07, 2012 1:34 PM
  • That worked great! and I threw the Write-Host line back in to get feedback:

    foreach($file in  $web.GetFolder($docLib).Files){
        if( $web.GetFolder($docLib).Files.Count -le 81){break}
    	Write-Host("DELETED FILE: " + $file.name)
        $docLib.Items.DeleteItemById($file.Item.ID)
    }


    If puzzles are good for your BRAIN then SharePoint will keep it really healthy!


    Ramona Maxwell MCPD SharePoint 2010, MCITP SQL Server 2008

    Friday, June 08, 2012 2:16 AM
  • I love SharePoint.  It is sometimes very predictable and sometimes I can see the solution even without trying. This is one of the reasons I like SharePoint.

    I still say this is not the best way to do this.


    ¯\_(ツ)_/¯

    Friday, June 08, 2012 3:17 AM