none
Tweaking script to work as needed RRS feed

  • Domanda

  • Hi,

    I have created a script to zip log files every week. Actually I am a newbie to PowerShell scripting, and got the pieces of code from different articles, and thinking that it will work, combined it together. However I get errors. This is my script :

    param
    (
        # The input folder containing the files to zip
        [Parameter(Mandatory = $true)]
        [string] $InputFolder,

        # The output folder that will contain the zip files
        [Parameter(Mandatory = $true)]
        [string] $OutputFolder
    )

    # Get the files which should be archived, without folders
    $files = Get-ChildItem -Path $InputFolder

    # List Files which will be archived
    $files

    foreach ($file in $files)
    {
    # Get year and Month of the file
    # I used LastWriteTime since this are synced files and the creation day will be the date when it was synced
    $year = $file.CreationTime.Year.ToString()
    $month = $file.CreationTime.Month.ToString("00")
    $monthname = (Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($month)
    #$week = $file.CreationTime.Week.ToString()
    #$day = $file.CreationTime.Day.ToString()
    #$hour = $file.CreationTime.Hour.ToString()

    # Out FileName, year and month
    $file.Name
    $year
    $month
    #$week

    Set-Variable SET_SIZE -option Constant -value 7
    $i = 0
    $week = 0
    #$name = NASAPP

    Get-ChildItem $InputFolder | ForEach-Object {
        $zipSetName = "NASAPP" + "_" + $monthname.ToUpper() + "_" + "W" + ($week + 1) + ".zip"
        Compress-Archive -Path $_.FullName -Update -DestinationPath "$OutputFolder\$zipSetName"
            $i++;

        if ($1 -eq $SET_SIZE) {
        $i = 0;
        $week++;
        }
    }

    }

    And this is the error I get  :

    -a----        17/1/2020   3:48 PM          51200 dummy_90.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_91.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_92.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_93.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_94.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_95.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_96.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_97.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_98.txt                                                                                          
    -a----        17/1/2020   3:48 PM          51200 dummy_99.txt                                                                                          
    dummy_1.txt
    2020
    01
    ZipArchiveHelper : The process cannot access the file 'C:\Testfolder1\NASAPP_JAN_W1.zip' because it is being used by another process.
    At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:632 char:30
    + ... sArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compr ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : PermissionDenied: (C:\Testfolder1\NASAPP_JAN_W1.zip:String) [Write-Error], IOException
        + FullyQualifiedErrorId : CompressArchiveUnauthorizedAccessError,ZipArchiveHelper
     
    dummy_10.txt
    2020
    01
    Set-Variable : Cannot overwrite variable SET_SIZE because it is read-only or constant.
    At C:\Users\Owner\Desktop\TestPowerShellModifiedtoArchive.ps1:35 char:1
    + Set-Variable SET_SIZE -option Constant -value 7
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : WriteError: (SET_SIZE:String) [Set-Variable], SessionStateUnauthorizedAccessException
        + FullyQualifiedErrorId : VariableNotWritable,Microsoft.PowerShell.Commands.SetVariableCommand
     
    ZipArchiveHelper : The process cannot access the file 'C:\Testfolder1\NASAPP_JAN_W1.zip' because it is being used by another process.
    At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:632 char:30
    + ... sArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compr ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : PermissionDenied: (C:\Testfolder1\NASAPP_JAN_W1.zip:String) [Write-Error], IOException
        + FullyQualifiedErrorId : CompressArchiveUnauthorizedAccessError,ZipArchiveHelper
     
    dummy_100.txt
    2020
    01
    Set-Variable : Cannot overwrite variable SET_SIZE because it is read-only or constant.
    At C:\Users\Owner\Desktop\TestPowerShellModifiedtoArchive.ps1:35 char:1
    + Set-Variable SET_SIZE -option Constant -value 7
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : WriteError: (SET_SIZE:String) [Set-Variable], SessionStateUnauthorizedAccessException
        + FullyQualifiedErrorId : VariableNotWritable,Microsoft.PowerShell.Commands.SetVariableCommand
     
    ZipArchiveHelper : The process cannot access the file 'C:\Testfolder1\NASAPP_JAN_W1.zip' because it is being used by another process.
    At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:632 char:30
    + ... sArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compr ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : PermissionDenied: (C:\Testfolder1\NASAPP_JAN_W1.zip:String) [Write-Error], IOException
        + FullyQualifiedErrorId : CompressArchiveUnauthorizedAccessError,ZipArchiveHelper

    I have created 200 dummy files, and ran the script above on my own laptop for testing purposes. The aim of the script on the actual production server is to zip the files every week, and move it to a monthly folder, which is located in a yearly folder. So the path of the file/folder would be NASApp/2015/JAN/NASAPP_JAN_W1.zip, where NASAPP_JAN_W1.zip is the name of the zipped file which contains files for week 1 in month JAN. So for week 2 the name would be NASAPP_JAN_W2.zip, and so on.

    Please help me resolve the error, as I do not know where/how to start.

    martedì 21 gennaio 2020 02:11

Tutte le risposte

  • You cannot access a file that is already in use.  Why are you using the command in this way?  Read the help for the command until you understand how it works.

    Get-ChildItem $InputFolder | 
      Compress-Archive -DestinationPath "$OutputFolder\$zipSetName"


    \_(ツ)_/

    martedì 21 gennaio 2020 02:21
    Moderatore
  • The error was gone after I changed my script. I overlooked that there were 2 loops that caused redundancy.

    This is the edited script :

    param
    (
        # The input folder containing the files to zip
        [Parameter(Mandatory = $true)]
        [string] $InputFolder,
    
        # The output folder that will contain the zip files
        [Parameter(Mandatory = $true)]
        [string] $OutputFolder
    )
    
    # Get the files which should be archived, without folders
    $files = Get-ChildItem -Path $InputFolder
    
    # List Files which will be archived
    $files
    
    foreach ($file in $files)
    {
    # Get year and Month of the file
    # I used LastWriteTime since this are synced files and the creation day will be the date when it was synced
    $year = $file.CreationTime.Year.ToString()
    $month = $file.CreationTime.Month.ToString("00")
    $monthname = (Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($month)
    #$week = $file.CreationTime.Week.ToString()
    #$day = $file.CreationTime.Day.ToString()
    #$hour = $file.CreationTime.Hour.ToString()
    
    # Out FileName, year and month
    $file.Name
    $year
    $month
    #$week
    
    Set-Variable SET_SIZE -option Constant -value 7
    $i = 0
    $week = 0
    #$name = NASAPP
    
    #Get-ChildItem $InputFolder | ForEach-Object {
    
    	$zipSetName = "NASAPP" + "_" + $monthname.ToUpper() + "_" + "W" + ($week + 1) + ".zip"
    	Compress-Archive -Path "$InputFolder" -Update -DestinationPath "$OutputFolder\$zipSetName"
        	$i++;
    
    	if ($1 -eq $SET_SIZE) {
    	$i = 0;
    	$week++;
    	}
    
    #}
    
    }

    The changes I made was commenting out the 2nd loop, changing the -Path value to "$InputFolder" and changing the output folder to a different one than C:\Testfolder. (This was the one I used earlier : both the Input Folder and Output Folder values were C:\Testfolder). I changed the output folder to C:\ZippedFiles, and the error was gone.

    However, this error still remains :

    dummy_100.txt
    2020
    01
    Set-Variable : Cannot overwrite variable SET_SIZE because it is read-only or constant.
    At C:\Users\Owner\Desktop\TestPowerShellModifiedtoArchive.ps1:35 char:1
    + Set-Variable SET_SIZE -option Constant -value 7
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : WriteError: (SET_SIZE:String) [Set-Variable], SessionStateUnauthorizedAccessException
        + FullyQualifiedErrorId : VariableNotWritable,Microsoft.PowerShell.Commands.SetVariableCommand

    I read some articles on this error, and they say that it could be something to do with the variable itself, in this case "SET-SIZE". However, I am not sure. What do I change this value to?

    martedì 21 gennaio 2020 03:26
  • Why do you use a constant?  Not needed. Just deine it as any other variable.


    \_(ツ)_/

    martedì 21 gennaio 2020 05:22
    Moderatore
  • I set the variable like this instead :

    Set-Variable SET_SIZE -value 7
    $i = 0
    $week = 0
    #$name = NASAPP

    The script now does not throw any error, the zip file NASAPP_JAN_W1.zip (only) gets created, and it does not stop at 7 files, instead it keeps zipping all the 200 files into the zip above.

    Why is this happening? Why does not proceed to NASAPP_JAN_W2.zip once it hits 7 files, and so on proceed?

    martedì 21 gennaio 2020 05:48
  • Place this at the beginning of your file:

    $SET_SIZE = 7
    $i = 0

    Change this:

    if ($i++ -gt $SET_SIZE) {


    \_(ツ)_/



    martedì 21 gennaio 2020 05:57
    Moderatore
  • The output is the same as before. All files get compressed into one zip file.
    martedì 21 gennaio 2020 06:22
  • The following will be easier for you to understand and fix.

    param(
        [Parameter(Mandatory)]
        [string]$InputFolder,
        [Parameter(Mandatory)]
        [string]$OutputFolder
    )
    $SET_SIZE = 7
    $i = 0
    $week = 0
    $files = Get-ChildItem -Path $InputFolder
    
    foreach ($file in $files){
    
        $monthname = (Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($file.CreationTime.Month).ToUpper()
    
    	$zipSetName = '{0}NASAPP_{1}_W(2).zip' -f $OutputFolder,$monthname,$week
    	Compress-Archive -Path $InputFolder -Update -DestinationPath $zipSetName
        
        if ($i++ -gt $SET_SIZE) {
    	    $i = 0;
    	    $week++;
    	}
    }
    

    What you appear to be trying to do doesn't make any sense.


    \_(ツ)_/

    martedì 21 gennaio 2020 06:22
    Moderatore
  • Thank you for the code. Edited it, and successfully executed to get the output needed.

    This is the tweaked version :

    param
    (
        # The input folder containing the files to zip
        [Parameter(Mandatory = $true)]
        [string] $InputFolder,
    
        # The output folder that will contain the zip files
        [Parameter(Mandatory = $true)]
        [string] $OutputFolder
    )
    
    $SET_SIZE = 7
    $i = 0
    $week = 0
    $files = Get-ChildItem -Path $InputFolder
    
    foreach ($file in $files){
    
    	$month = $file.CreationTime.Month.ToString("00")
    	$monthname = (Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($month)
    	$mont = $monthname.ToUpper()
    
    	$zipSetName = "NASAPP_{0}_W{1}.zip" -f $mont,$week
    	Compress-Archive -Path $InputFolder -Update -DestinationPath "$OutputFolder\$zipSetName"
        
        	if ($i++ -gt $SET_SIZE) {
    	    $i = 0;
    	    $week++;
    	}
    }

    Now I need another help, whereby I need to group each archived file to five sets (i.e, one month has five weeks or less). The script above successfully creates zip files of 7 days in an incremental order, which is what I want, however, I need to make a bit of modification, whereby I need the script to renumber the archive to W1 after five zips. So for example for JAN, if the archive has reached number 5, then the next archive will be named the following month, and the week will be back to 1.

    January zips :

    NASAPP_JAN_W1.zip, NASAPP_JAN_W2.zip, NASAPP_JAN_W3.zip, NASAPP_JAN_W4.zip, NASAPP_JAN_W5.zip

    The following month will be Feb, so the zips will be with a change in month, but for week back to 1  :

    NASAPP_FEB_W1.zip, NASAPP_FEB_W2.zip, NASAPP_FEB_W3.zip, NASAPP_FEB_W4.zip


    • Modificato anaigini martedì 21 gennaio 2020 10:11
    martedì 21 gennaio 2020 10:10
  • I created this code excerpt to do the job I need :

    $j = 0
    $monts = "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEPT", "OCT", "NOV", "DEC"
    $monts.gettype()
    [System.Collections.ArrayList]$ArrayList1 = $monts
    $ArrayList1.GetType()
    for $k in $ArrayList1
    Get-ChildItem $InputFolder | ForEach-Object {
    ls *$k | Foreach {$l=1} {Rename-Item $_ -NewName ("NASAPP_$k_W{0}.jpg" -f $l++) -whatif}
    $j++;
    }
    Is this correct?

    martedì 21 gennaio 2020 10:56
  • You don't have to create those lists by yourself:

    (Get-Culture).DateTimeFormat.AbbreviatedMonthNames
    
    # or
    
    (Get-Culture).DateTimeFormat.MonthNames


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    martedì 21 gennaio 2020 12:09
  • I created this code excerpt to do the job I need :

    $j = 0
    $monts = "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEPT", "OCT", "NOV", "DEC"
    $monts.gettype()
    [System.Collections.ArrayList]$ArrayList1 = $monts
    $ArrayList1.GetType()
    for $k in $ArrayList1
    Get-ChildItem $InputFolder | ForEach-Object {
    ls *$k | Foreach {$l=1} {Rename-Item $_ -NewName ("NASAPP_$k_W{0}.jpg" -f $l++) -whatif}
    $j++;
    }
    Is this correct?

    There is no way to figure out what you are trying to do.  In every post you change the rules.  YOU have to get a clear statement of your intent and then stick to it.  We cannot incrementally write code for you.  Pleas take time to learn basic PowerShell from a reliable source like a book or web tutorial.

    Learning to script properly with PowerShell


    \_(ツ)_/

    martedì 21 gennaio 2020 17:49
    Moderatore
  • Hi,

    Was your issue resolved?

    If you resolved it using our solution, please "mark it as answer" to help other community members find the helpful reply quickly.

    If you resolve it using your own solution, please share your experience and solution here. It will be very beneficial for other community members who have similar questions.

    If no, please reply and tell us the current situation in order to provide further help.

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    lunedì 27 gennaio 2020 06:39
    Moderatore
  • Unfortunately, the script that I tested functional does not function correctly anymore, and even I am not sure why. One again, it zips all files into one zip, and this time. the problem is although it prints the zip names in sequential order, it prints like this :

    NASAPP_MAY_W1

    NASAPP_MAY_W2

    NASAPP_MAY_W3

    NASAPP_MAY_W4

    NASAPP_JUN_W4

    NASAPP_JUN_W5

    NASAPP_JUN_W6

    NASAPP_JUN_W7

    Why does it print JUN_W4 after MAY_W4? and not JUN_W5? Has the date of the files caused some complications? I created dummy files dated JAN 2015 (31 files), SEPT 2016 (30 files), and JUL 2017 (31 files).

    This is my script :

    param
    (
        # The input folder containing the files to zip
        [Parameter(Mandatory = $true)]
        [string] $InputFolder,
    
        # The output folder that will contain the zip files
        [Parameter(Mandatory = $true)]
        [string] $OutputFolder
    )
    
    $SET_SIZE = 7
    $i = 0
    $week = 1
    $files = Get-ChildItem -Path $InputFolder
    
    foreach ($file in $files){
    
        $month = $file.LastWriteTime.Month.ToString("00")
        $monthname = (Get-Culture).DateTimeFormat.GetAbbreviatedMonthName($month)
        $mont = $monthname.ToUpper()
    
        $zipSetName = "NASAPP_{0}_W{1}.zip" -f $mont,$week
        Compress-Archive -Path $InputFolder -Update -DestinationPath "$OutputFolder\$zipSetName"
        
            if ($i++ -gt $SET_SIZE) {
            $i = 0;
            $week++;
        }
    
    }
    I did not add the code excerpt to change the file names because the code above to zip files does not work in the first place.

    What am I doing wrong?


    • Modificato anaigini lunedì 27 gennaio 2020 11:32
    lunedì 27 gennaio 2020 11:31
  • The week number of the year can exist in two months.  Part of your problem is, as I tries to note above, what you are trying to do is state din ambiguous terms.  You need to think about how your design works which is driven by being able to make a clear statement of what your intentions are and why.


    \_(ツ)_/

    lunedì 27 gennaio 2020 16:22
    Moderatore
  • I think my intentions I quite clear, as I have repeated it several times.

    However the problem is understanding the correct syntax to achieve what I need. So what is the correct way for the script to scan through files of different dates and only zip 7 files , instead of the entire 31 days' files. I don't know why the script still zips all 31 files in a month, even when the code says zip once 7 files are reached.

    Thx.

    martedì 28 gennaio 2020 03:30
  • I think my intentions I quite clear, as I have repeated it several times.

    However the problem is understanding the correct syntax to achieve what I need. So what is the correct way for the script to scan through files of different dates and only zip 7 files , instead of the entire 31 days' files. I don't know why the script still zips all 31 files in a month, even when the code says zip once 7 files are reached.

    Thx.

    Are you saying that you want to zip 7 files at a time?


    \_(ツ)_/

    martedì 28 gennaio 2020 04:06
    Moderatore
  • Yes, I want to zip 7 files at a time.
    martedì 28 gennaio 2020 08:39
  • Yes, I want to zip 7 files at a time.

    To easily partition a collection we can do this:

    [collections.arraylist]$files = get-childitem *.txt -File
    $remaining = $files.Count
    for($i = 0;$i -lt $files.Count;$i+=7){
        Try{
            $files.GetRange($i,7) | Compress-Archive archive.zip
            $remaining -= 7
        }
        Catch{
            $files.GetRange($i,$remaining) | Compress-Archive archive.zip
        }
    }


    \_(ツ)_/



    martedì 28 gennaio 2020 10:16
    Moderatore