none
Powershell vs. Powershell ise RRS feed

  • Frage

  • Wie arbeitet die powershell ise anders als die normale Powershell?

    Hintergrund meiner Frage ist das ich ein Skript geschrieben habe, welches in der PS ise ohne Probleme läuft aber in der PS Fehler wirft. Die Fehler scheinen irgendwie mit Variablen die ich definiert habe zu tun zu haben.

    Kann mir hier jemand helfen?

    Freitag, 7. Februar 2020 22:00

Antworten

  • Moin,

    ja, die ISE ist ein anderer PowerShell-Host und arbeitet teilweise anders, deshalb lautet das dritte Gebot des Skriptens auch "Du sollst immer in dem Host testen, in dem es auch produktiv ausgeführt wird". Unter anderem gibt es in ISE verbotene DOS-Befehle und -Programme, die nicht aufgerufen werden können, und ähnliches mehr.

    Ein typisches Phänomen in ISE ist, dass wenn Du ein Skript in ISE lädst und mit F5 ausführst, die ganzen Variablen erhalten bleiben, und wenn Du sie z.B. in einem anderen Skript oder bei vorheriger Ausführung desselben Skriptes gesetzt hast, sind die Werte halt da. Vielleicht ist das ja Dein Problem. 


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Freitag, 7. Februar 2020 22:10
  • Da scheinen die beiden ersten Programm beim ablegen etwas anders zu machen als die ISE.

    Check doch einfach mal, welche Kodierung die ISE benutzt und stell dann in Deinem Lieblings-Code-Editor die gleiche Kodierung ein. ;-) VSCode z.B. kann man sich ziemlich kleinteilig anpassen.

    Bei mir erzeugt die ISE Dateien mit UTF-8-BOM Kodierung.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 11. Februar 2020 21:40

Alle Antworten

  • Moin,

    ja, die ISE ist ein anderer PowerShell-Host und arbeitet teilweise anders, deshalb lautet das dritte Gebot des Skriptens auch "Du sollst immer in dem Host testen, in dem es auch produktiv ausgeführt wird". Unter anderem gibt es in ISE verbotene DOS-Befehle und -Programme, die nicht aufgerufen werden können, und ähnliches mehr.

    Ein typisches Phänomen in ISE ist, dass wenn Du ein Skript in ISE lädst und mit F5 ausführst, die ganzen Variablen erhalten bleiben, und wenn Du sie z.B. in einem anderen Skript oder bei vorheriger Ausführung desselben Skriptes gesetzt hast, sind die Werte halt da. Vielleicht ist das ja Dein Problem. 


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Freitag, 7. Februar 2020 22:10
  • OK, das ist ja echt blöd, im ISE kann ich ja ganz gut Entwickeln, was bringt mir das aber wenn ich es dann in der normalen PS nicht verwenden kann?

    Allerdings habe ich es noch nicht ganz verstanden. Ich habe mal versucht mein Code zu Stückel um zu sehen wo mein Problem ist: Hier mal der Teil den ich jetzt noch ausführe (Serverinfos habe ich natürlich unkenntlich gemacht):

    # Variablen definieren
    $Stunde = get-date -format HH
    $Minute = get-date -format mm
    $Jahr = get-date -format yyyy
    $Monat = get-date -format MM
    $Tag = get-date -format dd
    $Jahr_Löschen = $Jahr - 1
    $Start_Date = "$Jahr.$Monat.$Tag"
    $Start_Datum = "$Tag.$Monat.$Jahr"
    $Start_Zeit = "${Stunde}:$Minute"
    $Start_Time = "$Stunde.$Minute"
    $Pfad_Backup = "O:\Homepage\Backup\DB-Sicherungen\" 
    $Pfad_Backup_Datum = "$Pfad_Backup_DB$Start_Date.$Start_Time\"
    $Pfad_Quelle = "/home/mather/backup_db/*"
    $WinSCP = "O:\Programme\PortableApps\WinSCPPortable\"
    $Puttykey = "O:\Programme\PortableApps\PuTTYPortable\App\putty\Matti_private.ppk"
    $Quelle_Server = "server"
    $Quelle_Fingerprint = "ssh-ed25519 256 0815"
    $Quelle_user = "user"
    
    # erzeugen des Sicherungsordners
    New-Item -Name "$Start_Date.$Start_Time" -ItemType Directory -Path $Pfad_Backup
    
    # Kopieren der Dateien vom Server
    try
    {
        # Load WinSCP .NET assembly
        Add-Type -Path (Join-Path $WinSCP "WinSCPnet.dll")
       # Add-Type -Path "WinSCPnet.dll"
     
        # Setup session options
        $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
            Protocol = [WinSCP.Protocol]::sftp
            HostName = $Quelle_Server
            UserName = $Quelle_user
            SshPrivateKeyPath = $Puttykey
            SshHostKeyFingerprint = $Quelle_Fingerprint
        }
     
        $session = New-Object WinSCP.Session
     
        try
        {
            # Connect
            $session.Open($sessionOptions)
     
            # Upload files
            $transferOptions = New-Object WinSCP.TransferOptions
            $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
     
            $transferResult =
                $session.getFiles($Pfad_Quelle, $Pfad_Backup_Datum, $False, $transferOptions)
     
            # Throw on any error
            $transferResult.Check()
     
        }
        finally
        {
            # Disconnect, clean up
            $session.Dispose()
        }
    }
    catch
    {
    }
    

    Als Fehlermeldung bekomme ich:

    gci : Der Pfad "C:\Users\Moe\2" kann nicht gefunden werden, da er nicht vorhanden ist.
    In O:\Organisation\Skripte\Backupskripte\Sicherung_DB_Backups_v118.ps1:73 Zeichen:18
    + $Anzahl_Ordner = gci $Pfad_Backup_Datum -Directory -Recurse | Measure ...
    +                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (C:\Users\Moe\2:String) [Get-ChildItem], ItemNotFoundException
        + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
    gci : Der Pfad "C:\Users\Moe\2" kann nicht gefunden werden, da er nicht vorhanden ist.
    In O:\Organisation\Skripte\Backupskripte\Sicherung_DB_Backups_v118.ps1:74 Zeichen:19
    + $Anzahl_Dateien = gci $Pfad_Backup_Datum -File -Recurse | Measure-Obj ...
    +                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (C:\Users\Moe\2:String) [Get-ChildItem], ItemNotFoundException
        + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

    Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
    In O:\Organisation\Skripte\Backupskripte\Sicherung_DB_Backups_v118.ps1:115 Zeichen:1
    + $smtp.Credentials = $Credentials.GetCredential($SMTP,“578”,“Basic”)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

    Den Ordner legt er mir noch an, aber beim Winscp bricht er ab. Der Fehler besagt ja unter anderem das er mit der Variable $Anzahl_Ordner ein Problem hat. Das habe ich gar nicht mehr in meinem Skript drin. Weil du aber geschrieben hast, das die ISE das global setzt, habe ich den Rechner durchgestartet um wieder "sauber" zu sein, aber auch das hat nix gebracht. 

    Ich versteh es nicht.

    Samstag, 8. Februar 2020 06:45
  • Du setzt nirgends (im gezeigten Code) die Variable $Pfad_Backup_DB.

    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 8. Februar 2020 07:19
  • OK, das ist ja echt blöd, im ISE kann ich ja ganz gut Entwickeln, was bringt mir das aber wenn ich es dann in der normalen PS nicht verwenden kann?

    Das hat niemand gesagt, nur, dass Du es vor der Produktionsfreigabe in dem Host testen musst, in dem es auch laufen wird.

    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 8. Februar 2020 07:20
  • ... im ISE kann ich ja ganz gut Entwickeln ...

    Vielleicht schaust Du Dir mal VSCode an. Da bekommt man deutlich mehr Hilfen an die Hand, die einem das Leben erleichtern. z.B. sieht man sehr leicht, wo überall Variablen benutzt werden, wenn man eine markiert. Man wird darauf hingewiesen, wenn man Variablen deklariert, sie aber nicht benutzt.

    Man kann sich auch noch zusätzliche Hilfen als Extension nachinstallieren. z.B. "Bracket Pair Colorizer 2"  ... das Ding färbt einem die zugehörigen Klammer-Päärchen unterschiedlich ein.

    Trotzdem musst Du natürlich am Ende Deinen Code im geplanten Ziel-Host testen - das nimmt Dir keine Entwicklungsumgebung ab.  ;-)


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Samstag, 8. Februar 2020 10:17
  • Ok, hab noch mal in Ruhe drüber geschaut und ihr habt natürlich recht. VSCode habe ich mir auch mal angeschaut, dass sieht ganz gut aus.

    Nun habe ich noch eine Zusatzfrage. Mein Code von oben funktioniert nun soweit. Jetzt habe ich noch ein Mailsversand ergänzt, aber irgendwie verarbeitet der die Umlaut nicht richtig, obwohl ich utf8 gestzt habe. Kann mir jemand sagen wo ich den Fehler habe?

    $SMTPServer = "server***.de"
    $SMTPPort = "587"
    $Username = "***"
    $Password = Get-Content O:\Organisation\Skripte\Backupskripte\PW_web304p1.txt | ConvertTo-SecureString
    
    $to = "***@***.de"
    $from = "***@***.de"
    
    $subject = "Backup erfolgreich übertragen"
    
    $body = "
        Hallo ***, <br>
        <br>
    	Die Abholung der Datenbankbackups vom Server $Quelle_Server wurde, in der Zeit von ${Start_Zeit}Uhr am $Start_Datum bis ${Ende_Zeit}Uhr am $Ende_Datum, erfolgreich durchgeführt.<br>
        Es wurden $Anzahl_Dateien Dateien und $Anzahl_Ordner Ordner übertragen. <br>
        Der Download belegt eine Größe von $Groesse_FS und liegt im Ordner $Pfad_Backup_Datum. <br>
        <br>
        Viele Grüße <br>
        ***
        "
    
    
    $message = New-Object System.Net.Mail.MailMessage
    $message.subject = $subject
    $message.subjectEncoding = [System.Text.Encoding]::UTF8
    $message.IsBodyHTML = $true
    $message.body = $body
    $message.bodyEncoding = [System.Text.Encoding]::UTF8
    
    $message.to.add($to)
    $message.from = $from
    
    $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
    $smtp.EnableSSL = $true
    $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
    $smtp.send($message)
    

    Dienstag, 11. Februar 2020 07:58
  • Funktioniert bei mir genau so, wie du es machst. Umlaute werden korrekt angezeigt.

    Gruß

    Dienstag, 11. Februar 2020 08:33
  • Komisch, bei mir sieht es so aus:

    Hallo ***,

    Die Abholung der Datenbankbackups vom Server *** wurde, in der Zeit von 09:41Uhr am 11.02.2020 bis 09:41Uhr am 11.02.2020, erfolgreich durchgeführt.
    Es wurden 0 Dateien und 0 Ordner übertragen.
    Der Download belegt eine Größe von 0,00 GB und liegt im Ordner O:\Homepage\Backup\DB-Sicherungen\2020.02.11.09.41\.

    Viele Grüße
    ***

    Dienstag, 11. Februar 2020 08:43
  • was sagt denn dein Mail Client zu der Mail? Ist sie denn wirklich UTF8 formatiert?
    Dienstag, 11. Februar 2020 09:35
  • Jetzt habe ich noch ein Mailsversand ergänzt ....

    ... mal unabhängig von den Fehlern ... gibt es einen bestimmten Grund, warum Du nicht einfach Send-MailMessage benutzt?

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 11. Februar 2020 09:38
  • Jetzt habe ich noch ein Mailsversand ergänzt ....

    ... mal unabhängig von den Fehlern ... gibt es einen bestimmten Grund, warum Du nicht einfach Send-MailMessage benutzt?

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Ich habe gesucht, wie man mails versenden kann, und da ist mir die Methode oben als erstes unter die Finger gekommen.
    Dienstag, 11. Februar 2020 10:41
  • Ich habe gesucht, wie man mails versenden kann, und da ist mir die Methode oben als erstes unter die Finger gekommen.
    OK, dann lies Dir doch mal bitte die HIlfe komplett durch ... inklusive der Beispiele. Ich glaube, das macht Dein Leben ein bissl einfacher.  ;-)

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 11. Februar 2020 12:12
  • Hi,

    also einige wollten Send-MailMessage schon mit der PowerShell 6 raus werfen. 

    Github

    Beste Gruesse
    brima

    Dienstag, 11. Februar 2020 14:00
  • ... also einige wollten Send-MailMessage schon mit der PowerShell 6 raus werfen.
    ... was aber mangels empfehlenswerter/besserer Alternativen auch in 7.0.0rc2 noch nicht passiert ist.  :-P

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 11. Februar 2020 14:12
  • Ich habe es auch mit send-MailMessage probiert, habe aber das gleiche Problem.

    Nun habe ich aber eine Lösung gefunden, wobei mir die Ursache nicht ganz klar ist. Wenn ich den Quellcode für die Mailübertragung mit dem normalen Editor von Windows oder mit Notepad++ in eine Datei speicher, dann funktioniert die UTF8-Übertragung nicht, speichere ich den Code in der PowerShell ISE in eine Datei, werden die Umlaute sauber übertragen. Da scheinen die beiden ersten Programm beim ablegen etwas anders zu machen als die ISE.

    Dienstag, 11. Februar 2020 19:52
  • Da scheinen die beiden ersten Programm beim ablegen etwas anders zu machen als die ISE.

    Check doch einfach mal, welche Kodierung die ISE benutzt und stell dann in Deinem Lieblings-Code-Editor die gleiche Kodierung ein. ;-) VSCode z.B. kann man sich ziemlich kleinteilig anpassen.

    Bei mir erzeugt die ISE Dateien mit UTF-8-BOM Kodierung.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 11. Februar 2020 21:40