0

I've written a Powershell script to zip up my files and copy them to a USB drive and it's working as intended. However, I decided to update the script and add an error log, should something occur, and store into a text file.

My Code:

[string]$zipPath="C:\Users\someuser\7z.exe"
[string]$drive="E:\"
[string]$securityBackup="Security"
[string]$tempSecurity="temp_security"
[string]$keepasscopy="keepass_copy"
[string]$setDate
[string]$userPath="C:\Users\someuser\"
[string]$errorReport
[string]$errorText="C:\Users\someuser\errorLog.txt"
$dateVar = Get-Date

function createErrorReport($writeError){

   $writeError += " " + $dateVar.ToString()

   if(Test-Path ($errorText)){

        $writeError | Add-Content $errorText
    }
    else
    {
        $writeError | Set-Content $errorText
    }

}




<#Checking to see if the E:\ Drive exists, if it doesn't exit the script, if it does proceed#>

if(Test-Path ($drive)){
    Write-Output ($drive + " Drive Exists")
}
Else{

  #  Write-Output ($drive + " Drive Doesn't Exist")
   # $errorReport= ($drive + " Drive Doesn't Exist")
   # createErrorReport($errorReport)
    exit
}



[string]$buildDay=($dateVar.day.ToString())
[string]$buildMonth=($dateVar.Month.ToString())
[string]$buildYear=($dateVar.Year.ToString())
[string]$buildHour=($dateVar.Hour.ToString())
[string]$buildMinute=($dateVar.Minute.ToString())
[string]$buildSecond=($dateVar.Second.ToString())


[int]$checkDay = 0
[int32]::TryParse($buildDay,[ref]$checkDay)

[int]$checkMonth = 0
[int32]::TryParse($buildMonth,[ref]$checkMonth)

<#Checking to see if the day/month is less than 10, so that a zero could be applied#>

if($checkNum -le 10){
  ($buildDay="0"+$buildDay)
}

if($checkMonth -le 10){
    ($buildMonth="0"+$buildMonth)
}
 <#Creating the setDate variable which is used as the name. That way the script can be run without user interaction anytime
   Using the current day, month, year hour, minute and second we construct a name to apply to our zip file. #>
$setDate = $buildDay + "-" + $buildMonth + "-" + $buildYear + "-" + $buildHour + $buildMinute + $buildSecond


<#Create a temporary security directory in the user's path to store the KeePass files#>
md ("C:\Users\someuser\" + $tempSecurity)

<#If statement to check to see if the above directory was created. If it evaluates to true proceed #> 
if(Test-Path ($userPath + $tempSecurity)){

    <#Copy all the items in the security folder to the temporary folder that was created#>
    <#Recurse: Ensures all files and folders are copied, not just the top level folder #>
    Copy-Item ($userPath + $securityBackup+"\*") ($userPath + $tempSecurity) -Recurse

    md ($userPath + $keepasscopy+"\"+$setDate)

    <#Check to see if the above folder, KeePass\setDate has been created #>
    if(Test-Path ($userPath + $keepasscopy+"\"+$setDate)){

        <#Copy all the items in the Security folder where KeePass is stored to the newly created directory of KeePass\setDate#>
        Copy-Item ($userPath + $securityBackup+"\*") ($userPath + $keepasscopy+"\"+$setDate) -Recurse

        <#Call the 7-zip .exe and create a zip archive of the KeePass folder in the KeePass\setDate Directory#>
        $invokeCommand = ($zipPath + (" a -tzip") + (" "+$drive + $setDate + ".zip") + (" " + $userPath + $keepasscopy+"\"+$setDate))

        <#Calls the command to be started#>
        Invoke-Expression $invokeCommand

        <#Provided that the zip file is created on the USB drive remove the KeePass copy and the temporary copy from the user directory#>
        if(Test-Path ($drive + $setDate + ".zip")){


        Remove-item ($userPath + $keepasscopy) -Recurse
        Remove-Item ($userPath + $tempSecurity) -Recurse

    }   <#If the script is unable to create a copy on the USB drive, then tell the user that a backup copy exists on the current user directory#>
    else{
        Write-Output ("Unable to create backup of KeePass in " +$drive +  " A backup copy exist " + $userPath + $keepasscopy+"\"+$setDate)
         $errorReport= ("Unable to create backup of KeePass in " +$drive +  " A backup copy exist " + $userPath + $keepasscopy+"\"+$setDate)
         createErrorReport($errorReport)
        exit
    }
  }
  else
  {
    Write-Output ("Unable to create KeePass copy in " + $userPath)
      $errorReport= ("Unable to create KeePass copy in " + $userPath)
      createErrorReport($errorReport)
    exit
  }

}
else{
    Write-Output ("Unable to create temporary folder in " +$userPath)
     $errorReport= ("Unable to create temporary folder in " +$userPath)
     createErrorReport($errorReport)
    exit
}

Problem:

My issue is the first if statement, it checks to see if the USB drive I'm copying to exists, now even if the drive does exist it will print to the screen that it doesn't and right below it, it will print it does and continue on as normal, even if I comment out the Write-Output $drive doesn't exist, for some reason it still prints it to the screen. In other words it prints the drive doesn't exist even if it's plugged in and the Windows Explorer can see and access it. Even if it says the drive doesn't exist, and below it, it says it does, the rest of the ELSE statement won't execute, meaning it doesn't create the log report.

11
  • First thing: $errorText is not in scope for the function createErrorReport. If you are doing this in ISE save, close and reopen and start again. Your variables/functions are saved between runs so you might be having odd behaviour. Does that drive exist BEFORE the powershell script is executed? Commented Feb 8, 2015 at 15:56
  • @Matt - I think you did it! How do I fix this behavior? Commented Feb 8, 2015 at 15:59
  • Which behavior are you referring to? Commented Feb 8, 2015 at 16:00
  • the errorText out of scope for the function. How do I fix it, so that everytime I run the ISE I don't see drive doesn't exist even if it does. Commented Feb 8, 2015 at 16:01
  • Does Get-PSDrive help out here at all? technet.microsoft.com/en-us/library/hh849796.aspx Commented Feb 8, 2015 at 16:02

1 Answer 1

0

You first if statement has a scope issue. Inside the function you have scope is with the variable $errorText which is declared outside the function.

[string]$errorText="C:\Users\someuser\errorLog.txt"

function createErrorReport($writeError){
       $writeError += " " + $dateVar.ToString()
        if(Test-Path ($errorText)){
            $writeError | Add-Content $errorText
        }
        else{
            $writeError | Set-Content $errorText
        }
}

You have a few ways to address this. Which one you pick boils down to preference and need.

You could use the $global scope keyword like in this answer

A better coding practice would be to declare the variable inside the function ( especially if it is not used anywhere else)

function createErrorReport($writeError){
    [string]$errorText="C:\Users\someuser\errorLog.txt"
    if(Test-Path ($errorText)){

    }
}

Or pass it as a parameter to the function

function createErrorReport($writeError, $errorText){
    if(Test-Path ($errorText)){
    }
}

createErrorReport "Some Error" "C:\Users\someuser\errorLog.txt"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.