Page 1 of 1

Powershell & NRDP

Posted: Wed Nov 23, 2016 9:11 am
by dLans
Hi guys,

I've been working on a Powershell script to monitor a SAP job that is being started by a task scheduler (Starting an important job this way is not my prefered way of doing things, I'm just the monitoring guy in this case ^^). So I wrote the below script which seems to be working just fine, however I stupidly made the mistake of adding the Nagios exits in the script as well. That would only work if Nagios were to one to start the script which is something we absolutely do not want.

So my question: Is there anyone with experience with pushing the exit codes from a PowerShell script to Nagios (with NRDP?)? So Nagios will not touch this script at all.

Code: Select all

#Execute commands and capture output
$File1 = "C:\temp\sap\connection.txt"
$File2 = "J:\usr\sap\inbound\processing\proces.txt"
$File3 = "C:\temp\sap\dgl.txt"


$DirectoryInfo = Get-ChildItem -force J:\usr\sap\inbound\ | Measure-Object
$DirectoryInfo.count

if($DirectoryInfo.count -eq 0)
    {
        if(Test-Path $File1)
            {
                if(Get-ChildItem -Path C:\temp\sap\ -File connection.txt | where {$_.Lastwritetime -lt (Get-Date).AddHours(-1)})
                    {
                        $ErrorMessage = "No Inbound DGL files have been received in the past hour"
                        Write-Host $ErrorMessage
                        Exit $ReturnStateCritical
                    }
            }
        else
            {
                New-Item C:\temp\sap\connection.txt -type file
            }
    }
else
    {
        Remove-Item C:\temp\sap\connection.txt -Recurse
        Move-Item J:\usr\sap\inbound\*.* J:\usr\sap\inbound\processing\
        Copy-Item J:\usr\sap\inbound\processing\*.* J:\usr\sap\inbound\processing\proces.txt
        if(Test-Path $File2)
            {
                "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\nwrfcsdk\bin\startrfc.exe" -3 -u **** -p **** -c 500 -l D -h **** -s 00 -E PATHNAME=J:\usr\sap\inbound\processing\proces.txt -E PORT=DGL_CAL_WM -F EDI_DATA_INCOMING > "C:\temp\sap\dgl.txt"
                if(Test-Path $File3)
                    {
                        if($File3 contains "")
                            {
                                $OKMessage = "OK: DGL job last run status contains no errors"
                                Write-Host $OKMessage
                                $RemoveOld = (Get-Date).AddDays(-7)
                                Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force
                                exit $ReturnStateOK
                            }
                        else
                            {
                                $ErrorMessage = "Critical: an error has been found processing the DGL job. Please check SAP"
                                Write-Host $ErrorMessage
                                Rename-Item "C:\temp\sap\dgl.txt" -NewName "DGL error $(Get-Date -f dd-MM-yyyy_HH_mm).txt"
                                $RemoveOld = (Get-Date).AddDays(-7)
                                Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force
                                exit $ReturnStateCritical
                            }
                    }
                else
                    {
                        $UnknownMessage = "DGL Inbound status is unknown. Please check if the process is working as expected."
                        Write-Host $UnknownMessage
                        $RemoveOld = (Get-Date).AddDays(-7)
                        Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force
                        exit $ReturnStateUnknown
                    }
            }
        else
            {
                $ErrorMessage = "ERROR: Data was copied from J:\usr\sap\inbound\ to processing but proces.txt was not found!"
                Write-Host $ErrorMessage
                $RemoveOld = (Get-Date).AddDays(-7)
                Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force
                exit $ReturnStateCritical
            }
    }

Re: Powershell & NRDP

Posted: Wed Nov 23, 2016 11:48 am
by rkennedy
That would only work if Nagios were to one to start the script which is something we absolutely do not want.
Could you please clarify what you mean by this? Nagios will not run the powershell script at all. It will be executed through your agent, which then passes the exit codes all the way down to Nagios.

Re: Powershell & NRDP

Posted: Thu Nov 24, 2016 4:48 am
by dLans
Yes, it is the NRPE agent installed that actually executes the Powershell commands and sends the exit code to Nagios. However it is Nagios that tells the NRPE agent to run that check. Its an important job and Nagios goes down more often than our PR1 system on which the job runs (neither go offline often, but we have had problems with Nagios before). We just don't want to start the Powershell script through NRPE and risk not running the job when Nagios goes offline.

I've been thinking about writing the exit code to a file and have a Nagios NRPE script check the contents of that file. That would probably be a workaround, but that would mean at least two scripts in two different places.

Re: Powershell & NRDP

Posted: Mon Nov 28, 2016 2:11 pm
by rkennedy
Ah - I understand a bit more now with your use case. Depending how it's executed specifically, this link may help you out - https://outsideit.net/monitoring-window ... led-tasks/ - it's well written by one of our community members.

As for the logic goes on your post, a temporary lock file would be the route that I would go that Nagios can read and report based off of. Since you're using NRDP though, you might be able to hook your Powershell script directly in to send information. See this link - http://nuxref.com/2016/11/24/nrdp-nagio ... entos-7-x/ (scroll down to NRDP Protocol) which outlines what the XML payload should look like that you send to Nagios.

Re: Powershell & NRDP

Posted: Fri Dec 23, 2016 3:21 am
by dLans
A bit late, but I just wanted to let you know I've got it working with help from the sources you provided. I''ll add my code below in the hopes someone might find parts of it usable.


Basically what we do:
- Check if directory is empty (which it should not be)
--> If it is, check if file connection.txt is older than one hour (file is deleted once files are detected in directory as to make sure we can monitor activity)
--> if it is not, report OK for it could happen that we don't receive any files for a short period.
- else, remove connection.txt and execute move command.
--> Check if file exists
---> if it does, execute rfc.exe
----> check if file contains ""
-----> if it does, report OK
-----> if it does not, report CRITICAL


Code: Select all

#NRDP Token
$token = "nloospr1nagioscheck"

#XML: Report success
$ReportSuccess = @"
<?xml version='1.0'?> 
<checkresults>
<checkresult type='service'>
<hostname>****</hostname>
<servicename>Scheduled DGL Job Status</servicename>
<state>0</state>
<output>Succesfully ran the DGL job</output>
</checkresult>
</checkresults>
"@


#XML: Report critical
$ReportCritical = @"
<?xml version='1.0'?> 
<checkresults>
<checkresult type='service'>
<hostname>****</hostname>
<servicename>Scheduled DGL Job Status</servicename>
<state>2</state>
<output>Critical: error processing the files. Please check the DGL process</output>
</checkresult>
</checkresults>
"@


#XML: Report critical if no inbound DGL deliveries were found in the past hour
$ReportCriticalNoInbound = @"
<?xml version='1.0'?> 
<checkresults>
<checkresult type='service'>
<hostname>****</hostname>
<servicename>Scheduled DGL Job Status</servicename>
<state>2</state>
<output>No Inbound DGL files have been received in the past hour</output>
</checkresult>
</checkresults>
"@


#XML: Report unknown status if the plugin lacks information
$ReportUnknown = @"
<?xml version='1.0'?> 
<checkresults>
<checkresult type='service'>
<hostname>****</hostname>
<servicename>Scheduled DGL Job Status</servicename>
<state>3</state>
<output>DGL Inbound status is unknown. Please check if the process is working as expected.</output>
</checkresult>
</checkresults>
"@


#XML: Report critical if data was copied but not processed
$ReportCrititcalIfCopied = @"
<?xml version='1.0'?> 
<checkresults>
<checkresult type='service'>
<hostname>****</hostname>
<servicename>Scheduled DGL Job Status</servicename>
<state>2</state>
<output>ERROR: Data was copied from J:\usr\sap\inbound\ to processing but proces.txt was not found!</output>
</checkresult>
</checkresults>
"@








#Execute commands and capture output
$File1 = "C:\temp\sap\connection.txt"
$File2 = "J:\usr\sap\inbound\processing\proces.txt"
$File3 = "C:\temp\sap\dgl.txt"


$DirectoryInfo = Get-ChildItem -force J:\usr\sap\inbound\ | Measure-Object
$DirectoryInfo.count

if($DirectoryInfo.count -eq 0)
    {
        if(Test-Path $File1)
            {
                if(Get-ChildItem -Path C:\temp\sap\ -File connection.txt | where {$_.Lastwritetime -lt (Get-Date).AddHours(-1)})
                    {
                        try
                            {
                                $ie = New-Object -Com 'internetExplorer.Application'
                                $ie.Navigate("http://*.*.*.*/nrdp/")
                                $ie.Visible= $false

                                while($ie.ReadyState -ne 4) {start-sleep -m 100} 

                                $doc = $ie.document
                                $ie.Document.getElementByID("1").value = $token
                                $ie.Document.getElementByID("2").value = $ReportCriticalNoInbound
                                $Link=$ie.Document.getElementByID("3")
                                $Link.click()
                            }

                    }
            }
        else
            {
                New-Item C:\temp\sap\connection.txt -type file
                try
                    {
                        $ie = New-Object -Com 'internetExplorer.Application'
                        $ie.Navigate("http://*.*.*.*/nrdp/")
                        $ie.Visible= $false

                        while($ie.ReadyState -ne 4) {start-sleep -m 100} 

                        $doc = $ie.document
                        $ie.Document.getElementByID("1").value = $token
                        $ie.Document.getElementByID("2").value = $ReportSuccess
                        $Link=$ie.Document.getElementByID("3")
                        $Link.click()
                    }
            }
    }
else
    {
        Remove-Item C:\temp\sap\connection.txt -Recurse
        Move-Item J:\usr\sap\inbound\*.* J:\usr\sap\inbound\processing\
        Copy-Item J:\usr\sap\inbound\processing\*.* J:\usr\sap\inbound\processing\proces.txt
        if(Test-Path $File2)
            {
                "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\nwrfcsdk\bin\startrfc.exe" -3 -u **** -p **** -c 500 -l D -h **** -s 00 -E PATHNAME=J:\usr\sap\inbound\processing\proces.txt -E PORT=DGL_CAL_WM -F EDI_DATA_INCOMING > "C:\temp\sap\dgl.txt"
                if(Test-Path $File3)
                    {
                        if($File3 contains "")
                            {

                                $RemoveOld = (Get-Date).AddDays(-7)
                                Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force

                                try
                                    {
                                        $ie = New-Object -Com 'internetExplorer.Application'
                                        $ie.Navigate("http://*.*.*.*/nrdp/")
                                        $ie.Visible= $false

                                        while($ie.ReadyState -ne 4) {start-sleep -m 100} 

                                        $doc = $ie.document
                                        $ie.Document.getElementByID("1").value = $token
                                        $ie.Document.getElementByID("2").value = $ReportSuccess
                                        $Link=$ie.Document.getElementByID("3")
                                        $Link.click()
                                    }
                            }
                        else
                            {
                                Rename-Item "C:\temp\sap\dgl.txt" -NewName "DGL error $(Get-Date -f dd-MM-yyyy_HH_mm).txt"
                                $RemoveOld = (Get-Date).AddDays(-7)
                                Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force

                                try
                                    {
                                        $ie = New-Object -Com 'internetExplorer.Application'
                                        $ie.Navigate("http://*.*.*.*/nrdp/")
                                        $ie.Visible= $false

                                        while($ie.ReadyState -ne 4) {start-sleep -m 100} 

                                        $doc = $ie.document
                                        $ie.Document.getElementByID("1").value = $token
                                        $ie.Document.getElementByID("2").value = $ReportCritical
                                        $Link=$ie.Document.getElementByID("3")
                                        $Link.click()
                                    }
                            }
                    }
                else
                    {
                        $RemoveOld = (Get-Date).AddDays(-7)
                        Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force

                        try
                            {
                                $ie = New-Object -Com 'internetExplorer.Application'
                                $ie.Navigate("http://*.*.*.*/nrdp/")
                                $ie.Visible= $false

                           while($ie.ReadyState -ne 4) {start-sleep -m 100} 

                                $doc = $ie.document
                                $ie.Document.getElementByID("1").value = $token
                                $ie.Document.getElementByID("2").value = $ReportUnknown
                                $Link=$ie.Document.getElementByID("3")
                                $Link.click()
                            }

                    }
            }
        else
            {
                $RemoveOld = (Get-Date).AddDays(-7)
                Get-ChildItem -Path "C:\temp\sap" -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RemoveOld } | Remove-Item -Force

                try
                    {
                        $ie = New-Object -Com 'internetExplorer.Application'
                        $ie.Navigate("http://*.*.*.*/nrdp/")
                        $ie.Visible= $false

                        while($ie.ReadyState -ne 4) {start-sleep -m 100} 

                        $doc = $ie.document
                        $ie.Document.getElementByID("1").value = $token
                        $ie.Document.getElementByID("2").value = $ReportCrititcalIfCopied
                        $Link=$ie.Document.getElementByID("3")
                        $Link.click()
                    }
            }
    }

Re: Powershell & NRDP

Posted: Tue Dec 27, 2016 2:41 pm
by dwhitfield
@dLans, thanks so much for posting the code! Is it ok if we go ahead and lock this thread?