Cannot Call A Method Error

This topic contains 6 replies, has 2 voices, and was last updated by  Olaf Soyk 11 months, 1 week ago.

  • Author
    Posts
  • #61497

    Jason
    Participant

    Hello All,

    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!

    All best...

    Jason

  • #61498

    Olaf Soyk
    Participant

    In line 5 you use a variable "$xdoc" but you did not fill it in. At least not in the part of the code you posted here.

    • #61501

      Jason
      Participant

      Ah, that makes sense! Thanks Olaf.

      I see that was a variable from another iteration of the script.

      When I took that line out completely I got no error. I dont think it is necessary because by the line preceding it:

      $LogFile=Get-Item C:\ProgramData\IDrive\IBCOMMON\logs\$iDriveAcct\$computer\*.xml | Sort-Object -Property LastWriteTime | Select-Object -Skip 1 -Last 1 | Get-Content
      

      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.

      Is this correct?

      Thanks again!

      Jason

  • #61510

    Olaf Soyk
    Participant

    Jason,

    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:

    $LogFile = Get-Item C:\ProgramData\IDrive\IBCOMMON\logs\*.xml | Sort-Object -Property LastWriteTime | Select-Object -Last 1 
    $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
    }

    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.

  • #61516

    Jason
    Participant

    Thanks again Olaf,

    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!

    All best...

    Jason

  • #61522

    Olaf Soyk
    Participant

    OK. Just a quick one before I go to bed: Try the following snippet and see if it contains what you expect

    $LogFile = Get-Item C:\ProgramData\IDrive\IBCOMMON\logs\*\*\*.xml | Sort-Object -Property LastWriteTime | Select-Object -Last 1 
    $LogFileContent = Get-Content -Path $LogFile
    $LogFileDate = $LogFile.LastWriteTime
    
    "'$($LogFile)'"
    "'$($LogFileDate)'"
    "'$($LogFileContent)'"
    

    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.

  • #61527

    Olaf Soyk
    Participant

    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.

    http://www.microsoftvirtualacademy.com/training-courses/getting-started-with-powershell-3-0-jump-start

    http://www.microsoftvirtualacademy.com/training-courses/advanced-tools-scripting-with-powershell-3-0-jump-start

    https://www.youtube.com/playlist?list=PL6D474E721138865A

    https://www.youtube.com/results?search_query=don+jones+toolmaking

    https://www.youtube.com/watch?v=SSJot1ycM70

You must be logged in to reply to this topic.