I am attempting to teach myself Powershell by trying to assemble a script for GFI Remote Management to check the iDrive cloud backup service on our servers. So far I have this much put together which seems to do what I want it to do but I am getting an error in the process that is tripping up my reporting.
Here is what i have so far:
$iDriveAcct=Get-Childitem -name C:\ProgramData\IDrive\IBCOMMON\logs\
$Computer=Get-Childitem -name C:\ProgramData\IDrive\IBCOMMON\logs\$iDriveAcct\
$LogDate=Get-ChildItem -Path C:\ProgramData\IDrive\IBCOMMON\logs\$iDriveAcct\$Computer\*.xml | Sort-Object -Property LastWriteTime | Select-Object -Skip 1 -Last 1 -ExpandProperty LastWriteTime
$LogFile=Get-Item C:\ProgramData\IDrive\IBCOMMON\logs\$iDriveAcct\$computer\*.xml | Sort-Object -Property LastWriteTime | Select-Object -Skip 1 -Last 1 | Get-Content
$BackupStatus = $xdoc.SelectNodes("//status") | % { $_.InnerText } | select -Unique
if ($LogFile -match "Success") {
Write-Host "The backup on $LogDate was Successful"
Exit 0
}
elseif ($Logfile -match "Failure") {
Write-Host "The backup on $LogDate has FAILED"
Exit 1001
}
elseif ($Logfile -match "Cancelled") {
Write-Host "The backup on $LogDate was CANCELLED"
Exit 1001
}
else {
Write-Host "Error, no status found for backup job on $LogDate"
Exit 1001
}
And here is the error that I get when I run it:
You cannot call a method on a null-valued expression.
At C:\Users\***\***\GFI - Scripts\iDrive\2017.01.07_iDrive_Testing.ps1:5 char:1
+ $BackupStatus = $xdoc.SelectNodes("//status") | % { $_.InnerText } | ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
The backup on 11/18/2016 23:19:59 has FAILED
If anyone could give me an idea of the mistake I have made I would really appreciate it!
it ran the Get-Content which would have loaded the content of the .xml file into memory for the if/then statement that follows can then use to evaluate.
actually I did not pay attention to you code before. I just read the error and pointed you there. When I take a closer look to you code I see some room for improvement.
You first 3 lines look pretty weird to me and I would expect them to produce errors. If I’m right your script should work this way too:
if ($LogFileContent -match “Success”) {
Write-Host “The backup on $LogDate was Successful”
Exit 0
}
elseif ($LogFileContent -match “Failure”) {
Write-Host “The backup on $LogFileDate has FAILED”
Exit 1001
}
elseif ($LogFileContent -match “Cancelled”) {
Write-Host “The backup on $LogFileDate was CANCELLED”
Exit 1001
}
else {
Write-Host “Error, no status found for backup job on $LogFileDate”
Exit 1001
}
But anyway even if this does what you expect. If your xml files are really xml files and not just text files with fancy extensions you miss the whole point of working with structured data in Powershell. The free XML CookBock written by Dr.T.Weltner might give you an idea of what I mean.
I think you should start to learn the basics of Powershell. I’m sure it will pay off for you in future. Some great points to start from you can find here: Beginner Sites and Tutorials.
I am going to go thru that XML CookBook, it looks just like the thing I need for some other parts of the script I would like to add in the future. That was one of the biggest challenges to me was understanding how you can pull data out of the XML file and assign it to variables within the script I could use for reporting, this looks to be the answer.
The way that iDrive places the Log file directory is essentially different on every computer as it uses the account name (email address) and the computer name in the path, this is why the first three lines are a bit wonky. I also discovered thru trial and error that you also had to account for if the account had possibly changed or if it was migrated from another PC/Server which means I could not use the COMPUTERNAME variable reliably. So far that is the best way I have been able to get it to find the right directory pretty reliably.
I really like the simplicity of your if/then statement. This makes much more sense to me as to how it should work. I am having one issue when trying to run it the way you suggested. The line that runs the Get-Content for the $LogFileContent variable throws up an error when it is run. Forgive me if I have changed something in your suggested code, here is what I have after re-writing what I had and using your suggested way:
$iDriveAcct = Get-Childitem -name C:\ProgramData\IDrive\IBCOMMON\logs\
$Computer = Get-Childitem -name C:\ProgramData\IDrive\IBCOMMON\logs\$iDriveAcct\
$LogFile = Get-Item C:\ProgramData\IDrive\IBCOMMON\logs\$iDriveAcct\$computer\*.xml | Sort-Object -Property LastWriteTime | Select-Object -Skip 1 -Last 1 | Get-Content
$LogFileContent = Get-Content -Path $LogFile
$LogFileDate = $LogFile.LastWriteTime
if ($LogFileContent -match "Success") {
Write-Host "The backup on $LogDate was Successful"
Exit 0
}
elseif ($LogFileContent -match "Failure") {
Write-Host "The backup on $LogFileDate has FAILED"
Exit 1001
}
elseif ($LogFileContent -match "Cancelled") {
Write-Host "The backup on $LogFileDate was CANCELLED"
Exit 1001
}
else {
Write-Host "Error, no status found for backup job on $LogFileDate"
Exit 1001
}
I get this error:
PS C:\Users\***> C:\Users\***\***GFI - Scripts\iDrive\Testing\2017.01.08_iDrive_Testing.ps1
Get-Content : Cannot find drive. A drive with the name '2017-01-08 00' does not exist.
At C:\Users\***\***\GFI - Scripts\iDrive\Testing\2017.01.08_iDrive_Testing.ps1:5 char:19
+ $LogFileContent = Get-Content -Path $LogFile
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (2017-01-08 00:String) [Get-Content], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetContentComma
I am going to begin to go thru the XML CookBook as well to see if I can figure out where I went wrong with this.
Thanks again for all your help! I really appreciate you taking the time!
If I’m right this should give you the name of your logfile enclosed in single quotes, the “lastwritetime” enclosed in single quotes and finaly the content of the xml file you are looking for enclosed in single quotes.
OK, now your error message: You changed my suggestion. You added in line 3 “| Get-Content” and in line 4 use “Get-Content” again. That does not work. That’s why you get the error. And btw. if you use “Select-Object -Last 1” it does not make sense at all that you use “-skip 1”. It’s obsolete.
You really should take the time to learn the basics of Powershell. You don’t even have to read a book you can watch videos.