igetyaall
Goto Top

Remote PS Session mit Invoke bzw Pipes

Hallo Zusammen,

ich habe folgendes vor:

ServerA = unsere PRTG Server für das Monitoring
ServerB = Exchange CAS HUB Server

Natürlich stehen hinter den Bezeichnungen ServerB & ServerA auch die korrekten Hostnames, diese habe ich nur aus Schutzgründen hierfür getauscht.

nun möchte ich über eine Powershell Sensor eine Abfrage für ein bestimmtes Postfach starten, welches die eingehenden Mails von Intern und extern sowie die Gesamte Menge zählt und in einem
jeweils eigenen Kanal wieder ausgibt.

param (
[String]$mailbox="xxxx@xxx.de  

$CurrentDate = Get-Date
$LastMonth = (($CurrentDate).AddMonths(-1)).ToUniversalTime().Month
$LastMonthYear = (($CurrentDate).AddMonths(-1)).ToUniversalTime().Year
$LastMonthName = $LastMonth | %{(Get-Culture).DateTimeFormat.GetMonthName($_)}
$LastMonthDays = [DateTime]::DaysInMonth($LastMonthYear, $LastMonth)
$StartOfPrevMonth = Get-Date -Month $LastMonth -Year $LastMonthYear -Day 1 -Hour 0 -Minute 0 -Second 0 
$EndOfPrevMonth = ($StartOfPrevMonth).AddMonths(1).AddTicks(-1)

$WeekCS=Get-TransportServer | get-messagetrackinglog  -Recipients:$mailbox -Start $StartOfPrevMonth -End $EndOfPrevMonth -ResultSize unlimited | where {$_.EventId -like "RECEIVE"}  


$InternWeekCS=$WeekCS| where {($_.Sender -like "*@intern.de") -or ($_.Sender -like "*@intern2.de")}  
$ExternWeekCS=$WeekCS| where {($_.Sender -notlike "*extern2.de") -and ($_.Sender -notlike "*@extern2.de") }   
$AllWeekCS=$WeekCS

$InternCountWeekCS=$InternWeekCS | measure
$InternSumWeekCS14=$InternCountWeekCS.count

$ExternCountWeekCS=$ExternWeekCS | measure
$ExternSumWeekCS14=$ExternCountWeekCS.count

$AllCountWeekCS=$AllWeekCS | measure
$AllSumWeekCS14=$AllCountWeekCS.count

$AllSumWeekCS14
$InternSumWeekCS14
$ExternSumWeekCS14


Hiermit bekomme ich erfolgreich die Werte ausgelesen auf dem Exchange Server.
Leider ist dieser keine Remote Probe von PRTG und aus diesem Grund muss ich das Script vom PRTG Server aus starten.

Hier nun das erweitere Script mit PS Remote Aufruf

param (
[String]$mailbox="xxx@xxx.de"  
)

#Exchange 2010 with current user
$ExchangeOrNLBFQDN = "ServerB"  
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$ExchangeOrNLBFQDN/PowerShell/" -Authentication Kerberos  
Import-PSSession $Session -DisableNameChecking -AllowClobber




$CurrentDate = Get-Date
$LastMonth = (($CurrentDate).AddMonths(-1)).ToUniversalTime().Month
$LastMonthYear = (($CurrentDate).AddMonths(-1)).ToUniversalTime().Year
$LastMonthName = $LastMonth | %{(Get-Culture).DateTimeFormat.GetMonthName($_)}
$LastMonthDays = [DateTime]::DaysInMonth($LastMonthYear, $LastMonth)
$StartOfPrevMonth = Get-Date -Month $LastMonth -Year $LastMonthYear -Day 1 -Hour 0 -Minute 0 -Second 0 
$EndOfPrevMonth = ($StartOfPrevMonth).AddMonths(1).AddTicks(-1)

invoke-Command -ComputerName $ExchangeOrNLBFQDN -Scriptblock  {$WeekCS= Get-TransportServer| get-messagetrackinglog  -Recipients:$mailbox -Start $StartOfPrevMonth -End $EndOfPrevMonth -ResultSize unlimited  | where {$_.EventId -like "RECEIVE"} }  

#ALTER CODE ohne Invoke:   $WeekCS= Get-TransportServer| get-messagetrackinglog  -Recipients:$mailbox -Start $StartOfPrevMonth -End $EndOfPrevMonth -ResultSize unlimited  | where {$_.EventId -like "RECEIVE"}  


$InternWeekCS=$WeekCS| where {($_.Sender -like "*@intern.de") -or ($_.Sender -like "*@intern2.de")}  
$ExternWeekCS=$WeekCS| where {($_.Sender -notlike "*extern2.de") -and ($_.Sender -notlike "*@extern2.de") }   
$AllWeekCS=$WeekCS

$InternCountWeekCS=$InternWeekCS | measure
$InternSumWeekCS14=$InternCountWeekCS.count

$ExternCountWeekCS=$ExternWeekCS | measure
$ExternSumWeekCS14=$ExternCountWeekCS.count

$AllCountWeekCS=$AllWeekCS | measure



Write-Host "<prtg>"  
        Write-Host "<result>"  
        Write-Host ("<channel>Gesamt Emails</channel>")  
        Write-Host ("<value>" + $AllSumWeekCS14 + "</value>")  
        Write-Host "<Mode>Absolute</Mode>"  
        Write-Host "</result>"  
                Write-Host "<result>"  
        Write-Host ("<channel>Interne Emails</channel>")  
        Write-Host ("<value>" + $InternSumWeekCS14 + "</value>")  
        Write-Host "<Mode>Absolute</Mode>"  
        Write-Host "</result>"  
                Write-Host "<result>"  
        Write-Host ("<channel>Gesamt Emails</channel>")  
        Write-Host ("<value>" + $ExternSumWeekCS14 + "</value>")  
        Write-Host "<Mode>Absolute</Mode>"  
        Write-Host "</result>"  
Write-Host "</prtg>"  

Remove-PSSession $Session


Leider bekomme ich ohne Invoke den Fehler das die Pipe nicht übergeben werden kann

Das Eingabeobjekt kann an keine Parameter des Befehls gebunden werden, da der Befehl keine Pipelineeingaben akzeptiert oder die Eingabe und deren Eigenschaften mit 
keinem der Parameter übereinstimmen, die Pipelineeingaben akzeptieren.
    + CategoryInfo          : InvalidArgument: (ServerB:PSObject) [Get-MessageTrackingLog], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Get-MessageTrackingLog
    + PSComputerName        : ServerB



wenn ich den Code mit invoke ausführe

Die Benennung "Get-TransportServer" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen Sie   
die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten), und wiederholen Sie den Vorgang.
    + CategoryInfo          : ObjectNotFound: (Get-TransportServer:String) , CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : ServerB
 


Vielleicht kann mir jemand helfen, vielen Dank!

Content-ID: 460092

Url: https://administrator.de/contentid/460092

Ausgedruckt am: 24.11.2024 um 02:11 Uhr

Dani
Lösung Dani 07.06.2019 um 15:01:02 Uhr
Goto Top
Moin,
Das Eingabeobjekt kann an keine Parameter des Befehls gebunden werden, da der Befehl keine Pipelineeingaben akzeptiert oder die Eingabe und deren Eigenschaften mit keinem der Parameter übereinstimmen, die Pipelineeingaben akzeptieren.
Funktioniert die Abfrage in der EMS wenn du diese manuell direkt auf dem Server ausführst?!


Gruß,
Dani
igetyaall
igetyaall 07.06.2019 aktualisiert um 15:18:33 Uhr
Goto Top
Hallo Dani,

wenn ich den ersten Codeblock ausführe auf dem EMS ohne die Remote Session zu starten ja.
Die Funktion liefert mir die korrekten Werte.

Ebenso habe ich von ServerA auch schon zuerst die Remote Session gestartet und einen Get-Transportserver ausgeführt und bekomme ein Ergebnis, aber sobald eine Pipe kommt wars das ....
Dani
Lösung Dani 07.06.2019 um 15:21:08 Uhr
Goto Top
Ebenso habe ich von ServerA auch schon zuerst die Remote Session gestartet und einen Get-Transportserver ausgeführt und bekomme ein Ergebnis, aber sobald eine Pipe kommt wars das .
Versuch es mit anstatt einer Pipe einmal mit einer foreach Schleife.


Gruß,
Dani
colinardo
Lösung colinardo 08.06.2019 aktualisiert um 11:59:12 Uhr
Goto Top
Servus @igetyaall .
Bei remote-Exchange Verbindungen gibt es einige Unterschiede zu beachten.
Der Grund ist das bei deiner genutzten Methode der Verbindungsherstellung mit dem Exchange keine vollständige Serialisierung der Objekte vorgenommen wird und deswegen deine Pipe fehlschlägt weil das nachfolgende CMDLet ein Objekt unbekannten Typs empfängt.

Damit das nicht passiert füge den Parameter ?SerializationLevel=Full bei der Verbindungsherstellung hinzu:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$ExchangeOrNLBFQDN/PowerShell/?SerializationLevel=Full" -Authentication Kerberos  
Dann funktioniert deine alte Methode mit der Pipe wieder.
Außerdem lässt sich die Verbindungsherstellung erheblich beschleunigen wenn man nur ein paar der CMDLets in die Session importiert:
https://devblogs.microsoft.com/scripting/speed-up-remote-powershell-conn ...

In deinem obigen Fall ist aber ist aber weder Invoke-Command noch eine Pipe nötig für dein Vorhaben, da du dir ja die CMDLets bereits die Exchange CMDLets in die Session geholt hast und Get-MessageTrackingLog einen -Server Parameter beinhaltet:
$WeekCS = Get-Messagetrackinglog -Server $ExchangeOrNLBFQDN -Recipients $mailbox -Start $StartOfPrevMonth -End $EndOfPrevMonth -ResultSize unlimited -EventID RECEIVE


back-to-topHinweise wenn ohne komplette Serialization gearbeitet wird (also ohne den oben genannten Parameter)

Ohne komplette Serialisation hat die Pipe mit Get-TransportServer per Remote mit Get-MessageTrackingLog unter Umständen einen Haken von zwei parallel ausgeführten Pipelines auf das Serverobjekt, die sich dann auch mal mit folgender Fehlermeldung bemerkbar macht (gerade bei älteren EX Servern öfter der Fall):
Die Pipeline wird nicht ausgeführt, da bereits eine andere Pipeline ausgeführt wird. Pipelines können nicht gleichzeitig ausgeführt werden.
    + CategoryInfo          : OperationStopped: (Microsoft.Power...tHelperRunspace:ExecutionCmdletHelperRunspace) , PSInvalidOperationException
    + FullyQualifiedErrorId : RemotePipelineExecutionFailed

Wenn mit es unbedingt mit Get-TransportServer ohne komplette Serialization in der Pipeline ausgeführt werden soll dann so (wie Dani schon angedeutet hat mit For-Each Schleife), aber zusätzlich Klammern um Get-TransportServer um das Problem mit den parallel ausgeführten Pipelines zu umgehen.
(Get-TransportServer) | %{Get-Messagetrackinglog -Server $_.PSComputername -Recipients $mailbox -Start $StartOfPrevMonth -End $EndOfPrevMonth -ResultSize unlimited -EventID RECEIVE}

Hoffe das klärt dein Kopfkratzen face-wink

Grüße Uwe
igetyaall
igetyaall 09.06.2019 um 11:53:22 Uhr
Goto Top
Hallo Uwe,

vielen Dank für deine Hilfe ! Ich werde es gleich am Dienstag testen und euch dann berichten face-smile

Auch @Dani vielen Dank!

schöne Feiertage noch
igetyaall
igetyaall 11.06.2019 um 08:52:59 Uhr
Goto Top
Ein Danke noch einmal an Uwe und Dani,

mithilfe des ?SerializationLevel=Full hat es geklappt!

VG

Gustav