locked
Powershell - Scripting Help with Get-Childitem RRS feed

  • Question

  • Hi,

    I have a script that runs every morning at 4am that look to see if two files are located there and then proceeds to restore a SQL Database if these files exists. 

    However once every 2 weeks, We get an issue where it fails to find the two files so doesn't restore the database but when i check in the morning the files were created a few hours before the script runs. 

    $path = gci "\\WEB\ws\logs" | ? { $_.PSIsContainer } | sort CreationTime -desc | select -f 1

    $logs = Get-ChildItem -Path $path.fullname -Recurse -file 
    $Filea = $Logs | where-object {$_.Name -eq "SuccessfulDataTransfers.txt"}
    $Fileb = $Logs | where-object {$_.Name -eq "VerifiedDataTransfers.txt"}
    Try{
    If ((test-path -path $Filea.fullname) -and (test-path -Path $Fileb.fullname)) 

    {
    Write-host "found both"

    }
    Catch{

    $email1 = @{
    From = "xxx@xxxx.co.uk"
    To = "xxx@xxxx.co.uk"

    Subject = " Beta Restore Failed"
    SMTPServer = "x.x.x.x"
    Body = "Restore - Please check if the files are located as one file is missing"
    }
    send-mailmessage @email1
    }

    is anyone able to give me a hand with trying to find out why or suggestions as to why?

    Thanks inadvance

    Friday, July 24, 2020 2:32 PM

Answers

  • Are you running the script from a PowerShell console, or from the ISE? If it's from the ISE (or another editor) the contents of the $FileA and $FileB will be "remembered" between executions. I added some "initialization" code to fix that.

    Here's a fresh copy of the script:

    $FileAName = "SuccessfulDataTransfers.txt"
    $FileBName = "VerifiedDataTransfers.txt"
    $LogFileName = "C:\SomeDirectory\SomeLogFile.txt"    #<== Change this to something on your system!
    $MissingFiles = @()
    $FileA = $FileB = $null     # make sure these are set to a known state at every execution
    $RunTime = Get-Date -Format "dddd MM/dd/yyyy HH:mm K"
    Add-Content -Path $LogFileName -Value "Begin file check at $RunTime"
    
    Try{
        $path = Get-ChildItem "\\WEB\ws\logs" -Directory -ErrorAction STOP |
            Sort-Object CreationTime -desc |
                Select-Object -first 1
        Add-Content -Path $LogFileName -Value ("Found directory $($path.fullname) at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        Add-Content -Path $LogFileName -Value ("Failed to find directory in path '\\WEB\ws\logs' at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    
    
    Try{
        $FileA = Get-ChildItem -Path ($path.fullname + "\" + $FileAName) -file -ErrorAction STOP
        Add-Content -Path $LogFileName -Value ("Found $FileAName at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        $MissingFiles += $FileAName
        Add-Content -Path $LogFileName -Value ("$FileAName was NOT found at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Try{
        $FileB = Get-ChildItem -Path ($path.fullname + "\" + $FileBName) -file -ErrorAction STOP
        Add-Content -Path $LogFileName -Value ("Found $FileBName at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        $MissingFiles += $FileBName
        Add-Content -Path $LogFileName -Value ("$FileBName was NOT found at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    If (-not ($FileA -and $FileB)){
        $MsgBody = "Restore - Please check if these files exist as the file(s) named {0} is/are missing" -f ($MissingFiles -Join " and ")
        $email = @{
            From = "xxx@xxxx.co.uk"
            To = "xxx@xxxx.co.uk"
            
            Subject = " Beta Restore Failed"
            SMTPServer = "x.x.x.x"
            Body = $MsgBody
            }
        Send-MailMessage $email
    }
    Else{
        $email = @{
            From = "XXXX@XXX.co.uk"
            To = "XXXX@XXX.co.uk"
            Subject = "Beta Restore"
            SMTPServer = "x.x.x.x"
            Body = "Crockford Restore - Found Both Files - Please find the results of the restore " + " " + "SOMETHING GOES HERE BUT I DON'T KNOW WHAT"
        }
        Send-MailMessage $email
    }


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    • Marked as answer by ClaireSim Thursday, July 30, 2020 10:19 AM
    Tuesday, July 28, 2020 7:09 PM

All replies

  • Is the e-mail sent? Is that how you discover the restore was not done?

    Adding "-ErrorAction STOP" to both "test-Path" cmdlets would be a good first step.

    Is this the directory/file hierarchy you're working with? Is it possible that the files are located in separate directories? Is that the reason you use the -Recurse when finding the child items? Any chance the files are located in different directories directly beneath the "logs" directory (e.g., one file in the "log1" directory and the other in "log2")?

    ws (share)
    .logs
    ..log1
    ...log1-1
    ....logfile1
    ....logfile2
    ...log1-2
    ....logfile1
    ...log1-3
    ..log2
    ...log2-1
    ..log3
    ..etc....


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, July 24, 2020 3:06 PM
  • Yes i have two email functions.

    1st : sends an email to advise the file's exist and includes the txt file of the SQL Restore so it shows this was successful.

    $email = @{
    From = "XXXX@XXX.co.uk"
    To = "XXXX@XXX.co.uk",
    Subject = "Beta Restore"
    SMTPServer = "x.x.x.x
    Body = "Crockford Restore - Found Both Files - Please find the results of the restore "+ "" + $Body
    }

    2nd: Sends an email if the files do not exist. 

    The log files are .txt

    \\WEB\ws\logs - is the directory and it finds the last folder created - $path = gci "\\WEB\ws\logs" | ? { $_.PSIsContainer } | sort CreationTime -desc | select -f 1

    The folder created in was called: 2272020 (this is depends on date) \\WEB\ws\logs\2272020  - This folder contains these files only. 

    $Filea = $Logs | where-object {$_.Name -eq "SuccessfulDataTransfers.txt"}

    $Fileb = $Logs | where-object {$_.Name -eq "VerifiedDataTransfers.txt"}

    Friday, July 24, 2020 3:25 PM
  • There was only one place where e-mail was sent in your example. My question was whether the e-mail notifying you of the missing file was sent or not.

    When you check to see if the files are present, are there any subdirectories in the ws\logs directory that have a newer creation date than the directory in which the files exist? Remember, you're basing the search location on the newest directory. If the directory 2272020 was created, say, at 2AM and the files at 3AM, and another directory was created at 3:30AM, your script will look (at 4AM) in the newer directory for the files.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Saturday, July 25, 2020 2:20 AM
  • There is one folder created in ws\logs which is created at 23:30 that night.  Then the files are created there depending if an upload happens. Which has happened for the past 4 months without no issue yet my script fails once every 2-3 weeks.

    Every night a folder is created in that one. So the script runs at 4am which detects the most recent one. 

    Monday, July 27, 2020 7:58 AM
  • See if adding some tracing to your script helps locate the problem. I don't know if what you posted is the entirety of your script, but if it is, this might serve as an example of what I mean. You could also add "Start-Transcript" to your original script if that's easier.

    FileAName = "SuccessfulDataTransfers.txt"
    $FileBName = "VerifiedDataTransfers.txt"
    $LogFileName = C:\SomeDirectory\SomeLogFile.txt
    $MissingFiles = @()
    $RunTime = Get-Date -Format "dddd MM/dd/yyyy HH:mm K"
    Add-Content -Path $LogFileName -Value "Begin file check at $RunTime"
    Try{
        $path = Get-ChildItem "\\WEB\ws\logs" -Directory -ErrorAction STOP |
            Sort-Object CreationTime -desc |
                Select-Object -first 1
        Add-Content -Path $LogFileName -Value ("Found directory $($path.fullname) at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        Add-Content -Path $LogFileName -Value ("Failed to find directory in path '\\WEB\ws\logs' at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    
    
    Try{
        $FileA = Get-ChildItem -Path ($path.fullname + "\" + $FileAName) -file -ErrorAction STOP
        Add-Content -Path $LogFileName -Value ("Found $FileAName at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        $MissingFiles += $FileAName
        Add-Content -Path $LogFileName -Value ("$FileAName was NOT found at" + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Try{
        $FileB = Get-ChildItem -Path ($path.fullname + + "\" + $FileBName) -file -ErrorAction STOP
        Add-Content -Path $LogFileName -Value ("Found $FileBName at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        $MissingFiles += $FileBName
        Add-Content -Path $LogFileName -Value ("$FileBName was NOT found" + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    If (-not ($FileA -and $FileB)){
        $MsgBody = "Restore - Please check if these files exist as the file(s) named {0} is/are missing" -f ($MissingFiles -Join " and ")
        $email = @{
            From = "xxx@xxxx.co.uk"
            To = "xxx@xxxx.co.uk"
            
            Subject = " Beta Restore Failed"
            SMTPServer = "x.x.x.x"
            Body = $MsgBody
            }
        Send-MailMessage $email
    }
    Else{
        $email = @{
            From = "XXXX@XXX.co.uk"
            To = "XXXX@XXX.co.uk"
            Subject = "Beta Restore"
            SMTPServer = "x.x.x.x"
            Body = "Crockford Restore - Found Both Files - Please find the results of the restore " + " " + "SOMETHING GOES HERE BUT I DON'T KNOW WHAT"
        }
        Send-MailMessage $email
    }
    


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Monday, July 27, 2020 3:18 PM
  • This doesn't quite work.

    I have removed one of the files i am testing with and i am getting:

    From the email results.

    Restore - Please check if these files exist as the file(s) named SuccessfulDataTransfers.txt and VerifiedDataTransfers.txt is/are missing

    Yet only one file is missing

    Tuesday, July 28, 2020 10:44 AM
  • Oops. Sorry. There's a superfluous "+" in the Get-ChildItem for one of the files.

    Remove it, or replace the line with this:

    $FileB = Get-ChildItem -Path ($path.fullname + "\" + $FileBName) -file -ErrorAction STOP

    There's also a missing "$" at the beginning of the very first line. I missed it when I selected the text from my editor to paste into my post.

        $FileAName = "SuccessfulDataTransfers.txt"


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


    Tuesday, July 28, 2020 2:55 PM
  • Thanks, That now works,

    However i am having an issue where the email shows:

    Restore - Please check if these files exist as the file(s) named SuccessfulDataTransfers.txt and VerifiedDataTransfers.txt is/are missing

    When only one of them is missing. 

    Tuesday, July 28, 2020 4:43 PM
  • Are you running the script from a PowerShell console, or from the ISE? If it's from the ISE (or another editor) the contents of the $FileA and $FileB will be "remembered" between executions. I added some "initialization" code to fix that.

    Here's a fresh copy of the script:

    $FileAName = "SuccessfulDataTransfers.txt"
    $FileBName = "VerifiedDataTransfers.txt"
    $LogFileName = "C:\SomeDirectory\SomeLogFile.txt"    #<== Change this to something on your system!
    $MissingFiles = @()
    $FileA = $FileB = $null     # make sure these are set to a known state at every execution
    $RunTime = Get-Date -Format "dddd MM/dd/yyyy HH:mm K"
    Add-Content -Path $LogFileName -Value "Begin file check at $RunTime"
    
    Try{
        $path = Get-ChildItem "\\WEB\ws\logs" -Directory -ErrorAction STOP |
            Sort-Object CreationTime -desc |
                Select-Object -first 1
        Add-Content -Path $LogFileName -Value ("Found directory $($path.fullname) at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        Add-Content -Path $LogFileName -Value ("Failed to find directory in path '\\WEB\ws\logs' at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    
    
    Try{
        $FileA = Get-ChildItem -Path ($path.fullname + "\" + $FileAName) -file -ErrorAction STOP
        Add-Content -Path $LogFileName -Value ("Found $FileAName at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        $MissingFiles += $FileAName
        Add-Content -Path $LogFileName -Value ("$FileAName was NOT found at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Try{
        $FileB = Get-ChildItem -Path ($path.fullname + "\" + $FileBName) -file -ErrorAction STOP
        Add-Content -Path $LogFileName -Value ("Found $FileBName at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    Catch{
        $MissingFiles += $FileBName
        Add-Content -Path $LogFileName -Value ("$FileBName was NOT found at " + (Get-Date -Format "dddd MM/dd/yyyy HH:mm K"))
    }
    If (-not ($FileA -and $FileB)){
        $MsgBody = "Restore - Please check if these files exist as the file(s) named {0} is/are missing" -f ($MissingFiles -Join " and ")
        $email = @{
            From = "xxx@xxxx.co.uk"
            To = "xxx@xxxx.co.uk"
            
            Subject = " Beta Restore Failed"
            SMTPServer = "x.x.x.x"
            Body = $MsgBody
            }
        Send-MailMessage $email
    }
    Else{
        $email = @{
            From = "XXXX@XXX.co.uk"
            To = "XXXX@XXX.co.uk"
            Subject = "Beta Restore"
            SMTPServer = "x.x.x.x"
            Body = "Crockford Restore - Found Both Files - Please find the results of the restore " + " " + "SOMETHING GOES HERE BUT I DON'T KNOW WHAT"
        }
        Send-MailMessage $email
    }


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    • Marked as answer by ClaireSim Thursday, July 30, 2020 10:19 AM
    Tuesday, July 28, 2020 7:09 PM