Warum funktioniert dieser New-Item-Befehl in Powershell, aber nicht in einem PS1-Skript?

Warum funktioniert dieser New-Item-Befehl in Powershell, aber nicht in einem PS1-Skript?

Ich stecke hier völlig fest und habe keine Ahnung, was ich tun soll: Ich habe ein interaktives Multiple-Choice-PowerShell-Skript, das ich für die Ops zusammenstelle, damit sie ein paar Minuten sparen, wenn sie schnelle Aufgaben auf Remotecomputern ausführen möchten.

Ich habe den gesamten Code für alle anderen Auswahlmöglichkeiten durch ersetzt You have selected #, damit ich niemanden mit dem restlichen Skriptinhalt langweile, aber die Auswahl 6macht mich verrückt.

Dies ist mein Ziel, aber ich komme noch nicht über den ersten Aufzählungspunkt hinaus:

  • Neue .vncDatei erstellen
  • Fügen Sie den Textkörper des Standard-VNC-Protokolls in die Datei ein
  • Füge danach $ComputerNamehinzuHost=
  • Starten Sie die Datei

Das Problem ist, dass die Datei unten überhaupt nicht erstellt wird. Wenn Sie sie direkt in Powershell kopieren und einfügen, funktioniert sie, wird aber nicht in einem Skript ausgeführt! Weiß jemand, woran das liegen könnte?

$commands = {
  function Show-Menu
  {
    param (
      [string]$Title = 'My Menu'
    )
    Clear-Host
    Write-Host "================ $Title ================"

    Write-Host "1: Press '1' (Description)."
    Write-Host "2: Press '2' (Description)."
    Write-Host "3: Press '3' (Description)."
    Write-Host "4: Press '4' (Description)."
    Write-Host "5: Press '5' (Description)."
    Write-Host "6: Press '6' To start a VNC Connection."
    Write-Host "Q: Press 'Q' to quit."
  }

  Show-Menu –Title 'My Menu'
  $selection = Read-Host "Please make a selection"
  switch ($selection)
  {
    '1' {
      "You have selected 1"
      sleep -seconds 2
    } '2' {
      "You have selected 2"
      sleep -seconds 2
    } '3' {
      "You have selected 3"
      sleep -seconds 2
    } '4' {
      "You have selected 4"
      sleep -seconds 2
    } '5' {
      "You have selected 5"
      sleep -seconds 2
    } '6' {
      $ComputerName = (Read-Host "ComputerName")
      {
        New-Item -Path "C:\Windows\Temp\$ComputerName.VNC"
        Set-Content "C:\Windows\Temp\$ComputerName.VNC" '
        [connection]
        host=$ComputerName
        port=5900
        [options]
        use_encoding_1=1
        copyrect=1
        viewonly=0
        fullscreen=0
        8bit=0
        shared=1
        belldeiconify=0
        disableclipboard=0
        swapmouse=0
        fitwindow=0
        cursorshape=1
        noremotecursor=0
        preferred_encoding=7
        compresslevel=-1
        quality=6
        localcursor=1
        scale_den=1
        scale_num=1
        local_cursor_shape=1'
      }
    } 'q' {
      #Closes the script
      return
    }
  }
  .$commands

}
&$commands

Antwort1

Wenn es direkt in Powershell kopiert/eingefügt wird, funktioniert es, wird aber nicht in einem Skript ausgeführt.

Das klingt ziemlich nach einer ungeeigneten Ausführungsrichtlinie. Sie können Get-ExecutionPolicyes überprüfen. Es gibt wahrscheinlich zurück Restricted.

Um dies dauerhaft zu ändern, führen Sie eine PowerShell mit erhöhten Rechten aus, führen Sie es aus Set-ExecutionPolicy RemoteSignedund bestätigen Sie mit y.

Um dies vorübergehend nur für die Ausführung Ihres Skripts zu ändern, können Sie es wie folgt ausführen:

powershell -ExecutionPolicy Bypass -File .\ScriptFile.ps1

So können Sie Ihr Skript aus einer Skriptdatei ausführen. Außerdem gibt es ein weiteres Problem, das bereits erwähnt wurde von@jfrmilner. In deiner 6. Option definierst du einen weiteren Skriptblock durch die zusätzlichen geschweiften Klammern:

...
} '6' {
      $ComputerName = (Read-Host "ComputerName")
      {
        # This just the definition of a scriptblock and will not be executed!
        # Instead, it will be sent to stdout.
      }
    } 'q' {
...

Die Definition selbst führt diese Zeilen nicht aus. Sie haben zwei Möglichkeiten, dieses Problem zu lösen:

  1. Lassen Sie die geschweiften Klammern weg und definieren Sie somit keinen Scriptblock. Die Zeilen werden ausgeführt.
  2. Stellen Sie dem Skriptblock ein Präfix voran .und er wird ausgeführt:
...
} '6' {
      $ComputerName = (Read-Host "ComputerName")
      .{
        # This is a scriptblock that will directly be executed!
      }
    } 'q' {
...

Antwort2

Das Gleiche gilt für das, was @Reg Edit und @Lee-Dailey sagen.

Wir können Ihren Bildschirm nicht sehen.

Und zweitens, warum sollten Sie erwarten …

&$commands

...dass dies in einem Skript funktioniert?

$commands ist keine auszuführende .ps1-Datei, sondern ein Skriptblock in Ihrem Skript.

Sie sagen, dass Sie in die powershell.exe-Konsole oder in ISE oder VSCode einfügen. Das sollte funktionieren, da Sie den Code geladen und von einer vorhandenen PowerShell-Instanz ausgeführt haben und der Code in dieser Instanz gelesen wurde.

Sofern dieser Code nicht als commands.ps1 gespeichert wird, ist &$commands hinfällig, da der Code nie in eine laufende oder aufgerufene PowerShell-Instanz geladen wird.

Außerdem wird dieser Skriptblock wirklich überhaupt nicht benötigt.

Versuchen Sie also Folgendes …

# VNCCommands.ps1
function Show-Menu
{
    param 
    (
        [string]$Title = 'My Menu'
    )

    Clear-Host
    $Banner = '='*16
    "$Banner $Title $Banner"

    "1: Press '1' (Description)."
    "2: Press '2' (Description)."
    "3: Press '3' (Description)."
    "4: Press '4' (Description)."
    "5: Press '5' (Description)."
    "6: Press '6' To start a VNC Connection."
    "Q: Press 'Q' to quit."
}

Show-Menu –Title 'My Menu'
$selection = Read-Host "Please make a selection"

switch ($selection)
{
    1 
    {
        "You have selected 1"
        sleep -seconds 2
    } 
    2 
    {
        "You have selected 2"
        sleep -seconds 2
    } 
    3 
    {
        "You have selected 3"
        sleep -seconds 2
    } 
    4 
    {
        "You have selected 4"
        sleep -seconds 2
    } 
    5 
    {
        "You have selected 5"
        sleep -seconds 2
    } 
    6 
    {
        $ComputerName = Read-Host -Prompt 'Enter a computer name: '
        If (-Not (Test-Path -Path "D:\temp\$ComputerName"))
        {New-Item -Path 'D:\Temp' -Name "$ComputerName.VNC" -ItemType File -Verbose}
        Else {Write-Warning -Message "D:\temp\$ComputerName.VNC creation failed"}
    } 
    'q' {return}
}

Ausführen ---

.\VNCCommands.ps1



# Results
<#
================ My Menu ================
1: Press '1' (Description).
2: Press '2' (Description).
3: Press '3' (Description).
4: Press '4' (Description).
5: Press '5' (Description).
6: Press '6' To start a VNC Connection.
Q: Press 'Q' to quit.
Please make a selection: 6
Enter a computer name: : test
VERBOSE: Performing the operation "Create File" on target "Destination: D:\Temp\test.VNC".


    Directory: D:\Temp


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         19-Jul-20     17:14              0 test.VNC
#>

verwandte Informationen