I have a powershell script that runs a command that extracts the available whitespace from each mail store on an exchange server. The command runs, but the format of the text looks too complex for the simple custom sensor so I changed it to display the results in XML, created a new advanced XML sensor and I get this response.

Error reading response: Junk after document element </prtg>

The bottom line is I do not understand how to format the text properly and I cant find all the answers in the documentation or on the forums. I am missing something and I am not sure what to do.

#start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://gemini1/PowerShell/ -Authentication Kerberos

#import new session

Import-PSSession $Session -DisableNameChecking

#Channel Definition (Not sure how to format this)
$CHANNELNAME= "DB WhiteSpace"

<prtg>
  <result>
	<channel>Identity</channel>
  </result>
  <result>
	</channel>AvailableNewMailboxSpace</channel> 
  </result>
  </prtg>

Get-MailboxDatabase -Status | select Identity,AvailableNewMailboxSpace | export-clixml c:\xmltest.xml

Get-Content c:\xmltest.xml

Exit 0

Article Comments

Hi,
may you post the full output of the script when running the same from powershell directly?
Best regards


Nov, 2012 - Permalink

When I run the script this is the output

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>Selected.System.Management.Automation.PSCustomObject</T>
      <T>System.Management.Automation.PSCustomObject</T>
      <T>System.Object</T>
    </TN>
    <MS>
      <S N="Identity">WH Employees 01</S>
      <S N="AvailableNewMailboxSpace">147.3 MB (154,402,816 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="1">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Old Employees 01</S>
      <S N="AvailableNewMailboxSpace">122.5 MB (128,450,560 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="2">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Old Employees 02</S>
      <S N="AvailableNewMailboxSpace">39.78 MB (41,713,664 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="3">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Service Mailboxes 01</S>
      <S N="AvailableNewMailboxSpace">930.7 MB (975,863,808 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="4">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">WH Employees 02</S>
      <S N="AvailableNewMailboxSpace">2.847 GB (3,056,926,720 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="5">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">WH Employees 03</S>
      <S N="AvailableNewMailboxSpace">80.56 MB (84,475,904 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="6">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">WH Employees 06</S>
      <S N="AvailableNewMailboxSpace">173.6 MB (182,059,008 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="7">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Spam 01</S>
      <S N="AvailableNewMailboxSpace">336.5 MB (352,878,592 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="8">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Mailbox Database 1640716322</S>
      <S N="AvailableNewMailboxSpace">1.688 MB (1,769,472 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="9">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">SyncTest</S>
      <S N="AvailableNewMailboxSpace">87.81 MB (92,078,080 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="10">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">WH Employees 15</S>
      <S N="AvailableNewMailboxSpace">1.454 GB (1,561,198,592 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="11">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">OC Employees 02</S>
      <S N="AvailableNewMailboxSpace">271.2 MB (284,393,472 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="12">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">OC Employees 11</S>
      <S N="AvailableNewMailboxSpace">86.5 MB (90,701,824 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="13">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Contractors 11</S>
      <S N="AvailableNewMailboxSpace">203.6 MB (213,483,520 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="14">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">WH Employees 14</S>
      <S N="AvailableNewMailboxSpace">105.5 MB (110,657,536 bytes)</S>
    </MS>
  </Obj>
  <Obj RefId="15">
    <TNRef RefId="0" />
    <MS>
      <S N="Identity">Remote Employees 01</S>
      <S N="AvailableNewMailboxSpace">5.042 GB (5,413,535,744 bytes)</S>
    </MS>
  </Obj>
</Objs>

Nov, 2012 - Permalink

Hi,
in order to use the script with PRTG the output has to in the following format:

<prtg>
  <result>
    <channel>First channel</channel>
    <value>10</value>
  </result>
  <result>
    <channel>Second channel</channel>
    <value>20</value>
  </result>
</prtg>

The error output would be:

<prtg>
  <error>1</error>
  <text>Your error message</text>
</prtg>

For further information please see either http://YOUR_PRTG_INSTALLATION/api.htm#tab7 or refer to the manual.


Nov, 2012 - Permalink

Thanks,

I understand that part. What I do not understand is how do I get powershell to output that format? Or do I run another script to change the format?

Ill read the docs again, but I am not understanding how I get from where I am to where I need to be.

Thanks.


Nov, 2012 - Permalink

Here is the new Script. I changed it and it looks like its in the correct format.

I still get this response in PRTG.

Error reading response: Junk after document element </prtg>

Any thoughts?

#start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://gemini1/PowerShell/ -Authentication Kerberos

#import new session

Import-PSSession $Session -DisableNameChecking

$server=Get-MailboxDatabase -Status | select Identity,AvailableNewMailboxSpace 

foreach ($_.Identity in $server)  {
$Name=$_.Identity
$Data=$_.AvailableNewMailboxSpace

Write-Host
"<prtg>"
  "<result>"
    "<channel>$Name</channel>"
    "<value>$Data</value>"
  "</result>"
"</prtg>"
}

Here is the new output

<prtg>
<result>
<channel>WH Employees 01</channel>
<value>169.3 MB (177,569,792 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Old Employees 01</channel>
<value>118 MB (123,731,968 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Old Employees 02</channel>
<value>9.031 MB (9,469,952 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Service Mailboxes 01</channel>
<value>931.8 MB (977,010,688 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>WH Employees 02</channel>
<value>2.708 GB (2,907,996,160 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>WH Employees 03</channel>
<value>68.06 MB (71,368,704 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>WH Employees 06</channel>
<value>131.5 MB (137,887,744 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Spam 01</channel>
<value>336.5 MB (352,878,592 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Mailbox Database 1640716322</channel>
<value>1.688 MB (1,769,472 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>SyncTest</channel>
<value>71.22 MB (74,678,272 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>WH Employees 15</channel>
<value>1.219 GB (1,308,524,544 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>OC Employees 02</channel>
<value>129.8 MB (136,118,272 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>OC Employees 11</channel>
<value>54.94 MB (57,606,144 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Contractors 11</channel>
<value>170.8 MB (179,142,656 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>WH Employees 14</channel>
<value>34.25 MB (35,913,728 bytes)</value>
</result>
</prtg>
<prtg>
<result>
<channel>Remote Employees 01</channel>
<value>4.921 GB (5,284,265,984 bytes)</value>
</result>
</prtg>

Nov, 2012 - Permalink

Hi,
the XML is still not in the correct format, you will have to adjust your script, like the following:

#start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://gemini1/PowerShell/ -Authentication Kerberos

#import new session

Import-PSSession $Session -DisableNameChecking

$server=Get-MailboxDatabase -Status | select Identity,AvailableNewMailboxSpace 

Write-Host "<prtg>"

foreach ($_.Identity in $server)  {
$Name=$_.Identity
$Data=$_.AvailableNewMailboxSpace

Write-Host
  "<result>"
    "<channel>$Name</channel>"
    "<value>$Data</value>"
  "</result>"
}
Write-Host "</prtg>"

Furthermore the $Data in the tag <value> has to be either a float or integer value. The following won't be allowed:

71.22 MB (74,678,272 bytes)

When using float as return value, a tag <float> has to be inserted between the <result> tags, which might look like this:

 "<result>"
    "<channel>$Name</channel>"
    "<value>$Data</value>"
    "<float>1</float>"
  "</result>"

Additional you might also want to use units and therefore the most easy way would be to convert all values to MB, then the script should look something like this:

 "<result>"
    "<channel>$Name</channel>"
    "<value>$Data</value>"
    "<float>1</float>"
    "<VolumeSize>MegaByte</VolumeSize>"
  "</result>"

Please note that none of the code above has been tested by me, so further adjustments might be necessary!

For further information please refer to the manual.


Nov, 2012 - Permalink

This script will produce the correct output but only in the Exchange Management Shell, when using regular powershell the hash table comes back blank. I am not sure why that is.

do you have any ideas on why the remote script would not work?

#start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://gemini1/PowerShell/ -Authentication Kerberos

#import new session

Import-PSSession $Session 
#Add-PsSnapin "Microsoft.Exchange.Management.PowerShell.E2010" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 

Invoke-Command -Session $Session -ScriptBlock {$server}

$free=@{Label="AvailableNewMailboxSpace";Expression={$_.AvailableNewMailboxSpace.ToMB()}}
$server=Get-MailboxDatabase -Status | select Identity,$free
#PRTG Formatting 

Write-Host "<prtg>"

foreach ($_.Identity in $server)  {
$Name=$_.Identity
$Data=$_.AvailableNewMailboxSpace
Write-Host
  "<result>"
    "<channel>$Name</channel>"
    "<value>$Data</value>"
  "</result>"

}


Write-Host "</prtg>"

Exit 0

Here is the output.

<result>
<channel>WH Employees 15</channel>
<value>1137</value>
</result>

<result>
<channel>OC Employees 02</channel>
<value>64</value>
</result>

<result>
<channel>OC Employees 11</channel>
<value>60</value>
</result>

<result>
<channel>Contractors 11</channel>
<value>162</value>
</result>


Nov, 2012 - Permalink

Hi,
first, you will have to adjust the script again as the XML has to start and end with <prtg> resp. </prtg>.
As regarding the remote powershell, you might have a look at this article and maybe search the KB further.
Best regards


Nov, 2012 - Permalink

I'm working with a Powershell custom,too and can you remove the "Write-host" stuff ? the normal way to send something to STDOUT is simply "sending" ist. like

"<prtg>"

foreach ($_.Identity in $server) { $Name=$_.Identity $Data=$_.AvailableNewMailboxSpace "<result>" "<channel>$Name</channel>" "<value>$Data</value>" "</result>" }

"</prtg>"

Can you run the script outside of PRTG and check the output there ? Are you sure you run the ""right" script ? and not an older version ? Because you have a Write-host "prtg" in your script but is is not in the output.


Nov, 2012 - Permalink

Almost there.

The custom unit does seem to be coming through. And none of the data is graphing. Works outside of that though. Please let me know what you think.

  1. start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://gemini1/PowerShell/ -Authentication Kerberos

  1. import new session

Import-PSSession $Session -DisableNameChecking

$free=@{E={ (($_.AvailableNewMailboxSpace -replace '.+\((.+) bytes\)','$1') -replace '[, ]','')/1MB };L="WhiteSpace (MB)"} $server=Get-MailboxDatabase -Status | select Identity,$free

  1. PRTG Formatting

Write-Host "<prtg>"

foreach ($_.Identity in $server) { $Name=$_.Identity $Data=$_.{WhiteSpace (MB)} Write-Host "<result>" "<channel>$Name</channel>" "<value>$Data</value>" "<CustomUnit>MB</CustomUnit>" "<VolumeSize>MegaByte</VolumeSize>" "<float>1</float>" "</result>"

}

Write-Host "</prtg>"

Exit 0


Nov, 2012 - Permalink

Here is the script I am using. Ill probably write the error and warning thresholds into the script. So far, I think I have it working.

The regex is a workaround because I ran into a problem of the remote powershell serializing the data and it would return null.

I dont know why the custom unit did not appear in the channel list.

Thanks Talk to you later.

{{{#start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://server/PowerShell/ -Authentication Kerberos

  1. import new session

Import-PSSession $Session -DisableNameChecking

$free=@{E={ (($_.AvailableNewMailboxSpace -replace '.+\((.+) bytes\)','$1') -replace '[, ]','')/1MB };L="WhiteSpace (MB)"} $server=Get-MailboxDatabase -Status | select Identity,$free

  1. PRTG Formatting

Write-Host "<prtg>"

foreach ($_.Identity in $server) { $Name=$_.Identity $Data=$_.{WhiteSpace (MB)} Write-Host "<result>" "<channel>$Name</channel>" "<value>$Data</value>" "<CustomUnit>MB</CustomUnit>" "<VolumeSize>MegaByte</VolumeSize>" "<float>1</float>" "</result>"

}

Write-Host "</prtg>"

Exit 0}}}


Nov, 2012 - Permalink

Please change the XML structure to

   "<result>"
    "<channel>$Name</channel>"
    "<value>$Data</value>"
    "<Unit>Custom</Unit>
    "<CustomUnit>MB</CustomUnit>"
    "<VolumeSize>MegaByte</VolumeSize>"
    "<float>1</float>"
  "</result>"

as outlined under What is the XML Schema for EXEXML sensor?


Nov, 2012 - Permalink

That works great, Thank You.

Is there any way to update all of the channels with the same settings? Without editing them individually?


Nov, 2012 - Permalink

I'm not quite sure I understand what you mean. Could you please elucidate?


Nov, 2012 - Permalink

I want to set the warning levels for all the channels. There are 15 channels so I would like to edit them in a batch or a template


Nov, 2012 - Permalink

I am very sorry this (a Multi-Edit on all Channels of a sensor) is not possible in the moment.


Nov, 2012 - Permalink

Then we are good for now.

Thanks for your help


Nov, 2012 - Permalink

One last question. It is possible to access the backend database somehow? I am thinking I can do update the channel data with an append query.

Is it possible to login to the database directly?


Nov, 2012 - Permalink

Hello,

no, there is no direct access to the database except through the API.

https://www.paessler.com/manuals/prtg/application_programming_interface_api_definition.htm


Nov, 2012 - Permalink

Can I make a template file for a custom sensor?


Nov, 2012 - Permalink

Yes, if you let PRTG write a device template of the device with custom sensors, they should be contained in it.


Nov, 2012 - Permalink

Hi guys, I've looked at this post some time ago. Thanks for sharing this info. It's a pity Whitespace channel is still missing from PRTG "Exchange Database (Powershell) sensor".

Back to the question - i can't make this script work in my test environment. Error i get: " Error reading response: Invalid XML (missing /prtg)"

Full script i try to use is below. Advice or pointing to the right direction would be much appreciated. Thanks.

#start new remote session from powershell

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://MyServerHostname/PowerShell/ -Authentication Kerberos

    import new session 

Import-PSSession $Session -DisableNameChecking

$free=@{E={ (($_.AvailableNewMailboxSpace -replace '.+\((.+) bytes\)','$1') -replace '[, ]','')/1MB };L="WhiteSpace (MB)"} $server=Get-MailboxDatabase -Status | select Identity,$free
Write-Host "<prtg>"

foreach ($_.Identity in $server) { $Name=$_.Identity $Data=$_.{WhiteSpace (MB)} 
Write-Host "<result>" 
		"<channel>$Name</channel>" 
		"<value>$Data</value>" 
		"<CustomUnit>MB</CustomUnit>" 
		"<VolumeSize>MegaByte</VolumeSize>" 
		"<float>1</float>" 
	"</result>"

}

Write-Host "</prtg>"

Exit 0

Jun, 2014 - Permalink

Hi,
could you enable the Write REsult to Disk option on tab Settings of the sensor?
This will create a file called REsult of Sensor XXXX.txt in folder <PRTG Data Directory>\Logs (Sensors). (Where XXXX refers to the sensor id)
Please post the contents of this file.


Jun, 2014 - Permalink