none
Remotezugriff über Powershell auf Exchange Server auf Exchange Management Shell RRS feed

  • Frage

  • Moin zusammen

    Seit einiger Zeit bin ich nun an einem Script dran mit folgender Funktion:

    • Einlesen von Benutzerinformationen
    • Kontrollieren von Benutzerinformationen
    • Falls Kontrolle ok, Informationen ausgeben und nachfragen, ob fortgefahren werden soll... (Nein = Ende)
    • Ja...
    •  --> Benutzer wird in AD erstellt
    •  --> Benutzer wird zu Gruppen hinzugefügt
    •  --> Benutzerprofilordner wird erstellt
    •  --> Berechtigungen auf Benutzerprofil werden angepasst
    •  --> Exchange Mailbox wird für einen bestehenden AD-Benutzer erstellt

    Ausgangslage:

    • Ausgeführt wird das Script auf einem von zwei Domänencontrollern (WS2k8R2)
    • Notwendige Remotezugriffe sind: PS-Script auf DC1 zu Exchange Server 2010 SP2 auf Exchange Management Shell

    Was geht/Was ich begreife:

    • Alles funktioniert, bis auf den Zugriff auf auf den Exchange Server

    Was nicht geht/Was ich nicht begreife:

    • Wie kann ich eine PSSession auf den Exchange aufbauen, und dabei die Exchange Management Shell verwenden? (Korrekter Weg/Syntax)

    Hier dazu noch mein momentaner Code:

    Function ExMailbox{
        try {
            $s = New-PSSession `
                    -ConfigurationName Microsoft.Exchange `
                    -ConnectionUri http://$exchangeserver/PowerShell/ `
                    -Authentication Kerberos `
                    -Credential $exchangecred `
                    -ErrorAction Stop
            Invoke-Command `
                -Session $s `
                -scriptblock {Enable-Mailbox -Identity "$name" -DisplayName "$name"}
            Remove-PsSession $s
        } catch {
            Write-Host "Could not connect to exchange!" -ForegroundColor Yellow
        }
    }

    Ich danke euch für eure Mühe und Zeit!

    Grüsse

    MDZekic

    Anfügung: Ich besitze nicht die Möglichkeit, diesen Code auf einem Exchange auszutesten =S Deshalb kann ich Code nicht testen sondern (lediglich) theoretisch posten/übernehmen.

    Eine missgünstige Situation... mein Fachverantwortlicher sagt jedoch, es kann auch so gelöst werden -.-...


    - Ich poste den Code in der Form, wie er ist und geben keine Garantie, dass er auf Anhieb funktioniert... alles ist individuell und niemand ist perfekt! - "Ich versuche den Leuten zu helfen mit dem Code, den ich habe, welche Sie nicht haben ... (Macht das Sinn?)" =)


    • Bearbeitet MDZekic Montag, 21. Mai 2012 07:21 Erweiterung
    Montag, 21. Mai 2012 06:52

Antworten

  • Moin,

    irgendwie sieht Dein Exception Handling etwas wirr aus :). Ich habe mir erlaubt, die Funktion zu ändern und bekomme dann folgenden Fehler: "Mailbox not created: Expandable strings are not allowed in restricted language mode or a Data section.". Darauf hatte ich ja schon hingewiesen, daß die Variable $name nicht auf dem Server vorhanden ist, und somit der Script Block dort nicht ausgeführt werden. Da die Exchange Shell ein Restricted Runspace ist, kannst Du noch nicht einmal Expandable Strings benutzten. Die Lösung. Den Namen in den ScriptBlock einbauen oder kann man über [scriptblock]::Create().

    Folgendes Script hat bei mir Funkioniert:

    Function ExMailbox2{
        Write-Host "============================================================" -ForegroundColor White
        Write-Host "Started creating mailbox on $exchangeserver"
        try
    	{
            $s = New-PSSession `
                -ConfigurationName Microsoft.Exchange `
                -ConnectionUri http://"$exchangeserver"/PowerShell/ `
                -Authentication Kerberos `
                -Credential $exchangecred `
                -ErrorAction Stop
                Write-Host "Connection successfull" -ForegroundColor DarkGreen
        }
    	catch 
    	{
            throw "Connection not successfull: $($_.Exception.Message)"
        }
    	
    	try
    	{
    		$scriptBlock = [scriptblock]::Create("Enable-Mailbox -Identity $name -DisplayName $name")
    		
            Invoke-Command `
                -Session $s `
                -scriptblock $scriptBlock `
                -ArgumentList $name `
                -ErrorAction Stop
            Write-Host "Mailbox successfully created" -ForegroundColor DarkGreen
        }
    	catch
    	{
            Write-Host "Mailbox not created: $($_.Exception.Message)" -ForegroundColor DarkYellow
        }
    	finally 
    	{
        	Remove-PsSession $s -ErrorAction Stop
            Write-Host "Remote session successfully removed" -ForegroundColor DarkGreen
        }
    	
        Write-Host "Finished creating mailbox on $exchangeserver" -ForegroundColor Black
        Write-Host "============================================================" -ForegroundColor Black
    }
    
    $exchangeserver = 'aex1'
    $exchangecred = New-Object System.Management.Automation.PSCredential("a\administrator", ("test" | ConvertTo-SecureString -Force -AsPlainText))
    $name = 'test2'

    Noch einfacher geht es aber, wenn Du Import-PSSession benutzt. Dann bleibt Deine ganze Logik auf dem Client, auf dem das Script läuft, und dann kannst Du auch Expandable Strings verwenden:

    Function ExMailbox2{
        Write-Host "============================================================" -ForegroundColor White
        Write-Host "Started creating mailbox on $exchangeserver"
        try
    	{
            $s = New-PSSession `
                -ConfigurationName Microsoft.Exchange `
                -ConnectionUri http://"$exchangeserver"/PowerShell/ `
                -Authentication Kerberos `
                -Credential $exchangecred `
                -ErrorAction Stop
                Write-Host "Connection successfull" -ForegroundColor DarkGreen
    			
    		Import-PSSession -Session $s -CommandName Enable-Mailbox, Get-Mailbox
        }
    	catch 
    	{
            throw "Connection not successfull: $($_.Exception.Message)"
        }
    	
    	try
    	{
    		Enable-Mailbox -Identity "$name" -DisplayName "$name"
    		
            Write-Host "Mailbox successfully created" -ForegroundColor DarkGreen
        }
    	catch
    	{
            Write-Host "Mailbox not created: $($_.Exception.Message)" -ForegroundColor DarkYellow
        }	
    	
        Write-Host "Finished creating mailbox on $exchangeserver" -ForegroundColor Black
        Write-Host "============================================================" -ForegroundColor Black
    }

    HTH,

    Raimund

    • Als Antwort markiert MDZekic Freitag, 25. Mai 2012 10:43
    Donnerstag, 24. Mai 2012 16:13

Alle Antworten

  • Hallo,

    leider habe ich keine passende Umgebung, um Deine Funktion kurz zu testen. Aber ein paar Anmerkungen:

    1. Was passiert denn, wenn Du den ScriptBlock durch ein einfaches Get-Mailbox ersetzt. Wenn das geht, ist die Verbindung zum Exchange Server schon mal kein Problem.

    2. Der ScriptBlock wird auf dem Exchange Server ausgeführt. Die Variable $name wird es dort wohl nicht geben. Der ScriptBlock müßte wahrscheinlich über Umwege erstellt werden. Ich würde erst einen String bauen, und wenn der fertig ist, diesen in einen ScriptBlock umwandeln: [scriptblock]::Create($script)

    3. Du fängst zwar die Exception ab, benutzt diese aber nicht. Was ist denn die Fehlermeldung in der Exception? Im Catch Block kannst Du auf diese über $_ zugreifen.

    -Raimund

    Montag, 21. Mai 2012 16:41
  • Hallo

    Moin Raimund =)

    leider habe ich keine passende Umgebung, um Deine Funktion kurz zu testen. Aber ein paar Anmerkungen:

    Naja, ich verstehe, dass es umständlich ist, dies aufzubauen... sonnst hätte ich auch eine Umgebung aufgebaut ;)

    1. Was passiert denn, wenn Du den ScriptBlock durch ein einfaches Get-Mailbox ersetzt. Wenn das geht, ist die Verbindung zum Exchange Server schon mal kein Problem.

    Also, ich habe mich inzwischen auch schlau gemacht, und dazu folgenden Code zusammengestellt:

    Function ExMailbox{
        try {
            Invoke-Command `
                -ComputerName "$exchangeserver" `
                -scriptblock {Enable-Mailbox -Identity "$name" -DisplayName "$name"} `
                -ArgumentList $name `
                -Credential $exchangecred `
                -ErrorAction Stop
            Write-Host "Mailbox created..." -ForegroundColor Green
        } catch {
            Write-Host "Could not create mailbox!" -ForegroundColor Yellow
        }
    }

    2. Der ScriptBlock wird auf dem Exchange Server ausgeführt. Die Variable $name wird es dort wohl nicht geben. Der ScriptBlock müßte wahrscheinlich über Umwege erstellt werden. Ich würde erst einen String bauen, und wenn der fertig ist, diesen in einen ScriptBlock umwandeln: [scriptblock]::Create($script)

    Dies habe ich in meinem jetzigen Code berücksichtigt... Danke für das Aufmerksam machen! Habe ich nicht gewusst =)

    3. Du fängst zwar die Exception ab, benutzt diese aber nicht. Was ist denn die Fehlermeldung in der Exception? Im Catch Block kannst Du auf diese über $_ zugreifen.

    Da ich leider ebenfalls nur beschränkt über Testmöglichkeiten verfüge, kann ich dies nur ungenau beschreiben! Der Verbindungsaufbau, soweit ich testen konnten, funktioniert einwandfrei. Ich prüfe die Verbindung vor der eigentlichen Funktion mit einem einfachen Enter-PsSession. Wobei ich an die Grenzen stosse ist, dass ich Befehle aus der Exchange Management Shell verwende. Er meldet lediglich, dass es nicht als cmdlet oder funktion erkannt wurde...

    Kann es sein, dass dies ein Modul ist, welches importiert werden muss? Ist dies ein PSSnap-In, welches ich vorher einbinden muss? (Back to Baiscs: Ich kanns halt leider nicht testen/finden :/)

    Ich danke dir für deine Antwort und deine Hilfe! Vllt passt dieser Code besser oder vllt siehst du noch andere fehler...deine sollten ausgemerzt sein =)

    Freundlicher Gruss

    MDZekic

    Angefügt: p.s. Du hast ne ganze Menge Punkte... (Hat mich gerade umgehauen...Nicht schlecht!)


    - Ich poste den Code in der Form, wie er ist und geben keine Garantie, dass er auf Anhieb funktioniert... alles ist individuell und niemand ist perfekt! - "Ich versuche den Leuten zu helfen mit dem Code, den ich habe, welchen Sie nicht haben ... (Macht das Sinn?)" =)


    • Bearbeitet MDZekic Dienstag, 22. Mai 2012 11:49 Anfügung
    Dienstag, 22. Mai 2012 11:47
  • Update:

    Momentan bin ich bei folgendem Stück Code angelangt:

    Function ExMailbox2{
        Write-Host "============================================================" -ForegroundColor White
        Write-Host "Started creating mailbox on $exchangeserver"
        try {
            $s = New-PSSession `
                -ConfigurationName Microsoft.Exchange `
                -ConnectionUri http://"$exchangeserver"/PowerShell/ `
                -Authentication Kerberos `
                -Credential $exchangecred `
                -ErrorAction Stop
                Write-Host "Connection successfull" -ForegroundColor Green
        } catch {
            Write-Host "Connection not successfull" -ForegroundColor Yellow
        } finally {
            try {
            Invoke-Command `
                -Session $s `
                -ScriptBlock {Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010} `
                -ErrorAction Stop
                Write-Host "Adding PsSnapIn successfull" -ForegroundColor Green
            } catch {
                Write-Host "Adding PsSnapIn not successfull" -ForegroundColor Yellow
            } finally {
                try {
                    Invoke-Command `
                        -Session $s `
                        -scriptblock {Enable-Mailbox -Identity "$name" -DisplayName "$name"} `
                        -ArgumentList $name `
                        -ErrorAction Stop
                    Write-Host "Mailbox successfully created" -ForegroundColor Green
                } catch {
                    Write-Host "Mailbox not created" -ForegroundColor Yellow
                } finally {
                    try {
                        Remove-PsSession $s `
                            -ErrorAction Stop
                        Write-Host "Remote session successfully removed" -ForegroundColor Green
                    } catch {
                        Write-Host "Remote session could not be removed!" -ForegroundColor Yellow
                    }
                }
            }
        }
        Write-Host "Finished creating mailbox on $exchangeserver"
        Write-Host "============================================================" -ForegroundColor White
    }

    Ich werde diesen Code testen und die Resultate hier zurückschreiben...
    Bis anhind danke ich schonmal Raimund für seine bisherige Unterstützung =)

    Mit feuchten Füssen
    MDZekic


    - Ich poste den Code in der Form, wie er ist und geben keine Garantie, dass er auf Anhieb funktioniert... alles ist individuell und niemand ist perfekt! - "Ich versuche den Leuten zu helfen mit dem Code, den ich habe, welchen Sie nicht haben ... (Macht das Sinn?)" =)

    Dienstag, 22. Mai 2012 14:42
  • Moin,

    irgendwie sieht Dein Exception Handling etwas wirr aus :). Ich habe mir erlaubt, die Funktion zu ändern und bekomme dann folgenden Fehler: "Mailbox not created: Expandable strings are not allowed in restricted language mode or a Data section.". Darauf hatte ich ja schon hingewiesen, daß die Variable $name nicht auf dem Server vorhanden ist, und somit der Script Block dort nicht ausgeführt werden. Da die Exchange Shell ein Restricted Runspace ist, kannst Du noch nicht einmal Expandable Strings benutzten. Die Lösung. Den Namen in den ScriptBlock einbauen oder kann man über [scriptblock]::Create().

    Folgendes Script hat bei mir Funkioniert:

    Function ExMailbox2{
        Write-Host "============================================================" -ForegroundColor White
        Write-Host "Started creating mailbox on $exchangeserver"
        try
    	{
            $s = New-PSSession `
                -ConfigurationName Microsoft.Exchange `
                -ConnectionUri http://"$exchangeserver"/PowerShell/ `
                -Authentication Kerberos `
                -Credential $exchangecred `
                -ErrorAction Stop
                Write-Host "Connection successfull" -ForegroundColor DarkGreen
        }
    	catch 
    	{
            throw "Connection not successfull: $($_.Exception.Message)"
        }
    	
    	try
    	{
    		$scriptBlock = [scriptblock]::Create("Enable-Mailbox -Identity $name -DisplayName $name")
    		
            Invoke-Command `
                -Session $s `
                -scriptblock $scriptBlock `
                -ArgumentList $name `
                -ErrorAction Stop
            Write-Host "Mailbox successfully created" -ForegroundColor DarkGreen
        }
    	catch
    	{
            Write-Host "Mailbox not created: $($_.Exception.Message)" -ForegroundColor DarkYellow
        }
    	finally 
    	{
        	Remove-PsSession $s -ErrorAction Stop
            Write-Host "Remote session successfully removed" -ForegroundColor DarkGreen
        }
    	
        Write-Host "Finished creating mailbox on $exchangeserver" -ForegroundColor Black
        Write-Host "============================================================" -ForegroundColor Black
    }
    
    $exchangeserver = 'aex1'
    $exchangecred = New-Object System.Management.Automation.PSCredential("a\administrator", ("test" | ConvertTo-SecureString -Force -AsPlainText))
    $name = 'test2'

    Noch einfacher geht es aber, wenn Du Import-PSSession benutzt. Dann bleibt Deine ganze Logik auf dem Client, auf dem das Script läuft, und dann kannst Du auch Expandable Strings verwenden:

    Function ExMailbox2{
        Write-Host "============================================================" -ForegroundColor White
        Write-Host "Started creating mailbox on $exchangeserver"
        try
    	{
            $s = New-PSSession `
                -ConfigurationName Microsoft.Exchange `
                -ConnectionUri http://"$exchangeserver"/PowerShell/ `
                -Authentication Kerberos `
                -Credential $exchangecred `
                -ErrorAction Stop
                Write-Host "Connection successfull" -ForegroundColor DarkGreen
    			
    		Import-PSSession -Session $s -CommandName Enable-Mailbox, Get-Mailbox
        }
    	catch 
    	{
            throw "Connection not successfull: $($_.Exception.Message)"
        }
    	
    	try
    	{
    		Enable-Mailbox -Identity "$name" -DisplayName "$name"
    		
            Write-Host "Mailbox successfully created" -ForegroundColor DarkGreen
        }
    	catch
    	{
            Write-Host "Mailbox not created: $($_.Exception.Message)" -ForegroundColor DarkYellow
        }	
    	
        Write-Host "Finished creating mailbox on $exchangeserver" -ForegroundColor Black
        Write-Host "============================================================" -ForegroundColor Black
    }

    HTH,

    Raimund

    • Als Antwort markiert MDZekic Freitag, 25. Mai 2012 10:43
    Donnerstag, 24. Mai 2012 16:13
  • Moin Raimund,

    Zuerst, mein Exceptionhandling kommt mir auch ein bisschen wirr vor... Ich hatte jedoch vor Augen, Schritt für Schritt  des Codes ausführen zu können und dabei festzustellen, wo der Fehler liegt... sorry =)

    Zweitens, da ich eben keine Testumgebung habe, konnte ich halt das Script (immernochnicht) testen. Im Bezug auf "Restricted Runspace": Das kenne ich nicht =S... Danke für Information und ich werde mich noch darüber schlau machen und hatte auch vorher auf dich hören sollen =) Ich dache durch das mitgeben der Variabel, könnte ich das von dir erwähnte Problem lösen... hatte jedoch keine Ahnung von dem "Restricted Runspace" (Hätte den Scriptblock vorher zusammenbauen sollen wie von dir erklärt)... Danke! =)

    Drittens, DANKE für deinen getesteten Code... Ich werde diesen Freitag (nächst möglicher Testtermin) testen und Rückmeldung geben in unserer Umgebung, wenn mögich zu beiden Codes... Im Bezug auf das Importieren der Session: Ich habe bewusst die Session nicht Importiert, da auch lediglich ein Befehl ausgeführt wird. Ich dachte, es reicht ein Invoke-Command mit dem Einbezug der Session =))... Danke für die doppelte Ausführung =)))

    p.s. Woher hast du so kurzfristig den Exchange her? =D

    Ich danke dir für deine geopferte Zeit bisher Raimund und gebe noch Rückmeldung!! =)

    Mit Feuchten Füssen

    MDZekic


    - Ich poste den Code in der Form, wie er ist und geben keine Garantie, dass er auf Anhieb funktioniert... alles ist individuell und niemand ist perfekt! - "Ich versuche den Leuten zu helfen mit dem Code, den ich habe, welchen Sie nicht haben ... (Macht das Sinn?)" =)


    • Bearbeitet MDZekic Donnerstag, 24. Mai 2012 17:55 Rechtschreibung =D
    Donnerstag, 24. Mai 2012 17:55
  • Moin Raimund

    Dein Code funzt wunderbar! Vielen Dank für deine Unterstützung! Wenn ich könnte, würde ich dich weiterempfehlen =))

    Mit Feuchten Füssen aus der Schweiz

    MDZekic


    - Ich poste den Code in der Form, wie er ist und geben keine Garantie, dass er auf Anhieb funktioniert... alles ist individuell und niemand ist perfekt! - "Ich versuche den Leuten zu helfen mit dem Code, den ich habe, welchen Sie nicht haben ... (Macht das Sinn?)" =)

    Freitag, 25. Mai 2012 10:44