¿Por qué este comando Nuevo elemento funciona en PowerShell pero no en un script de PS1?

¿Por qué este comando Nuevo elemento funciona en PowerShell pero no en un script de PS1?

Totalmente atrapado aquí y no tengo idea de qué hacer: tengo un script Powershell interactivo de opción múltiple que estoy preparando para las operaciones para que se reduzcan unos minutos cada vez que quieran realizar tareas rápidas en computadoras remotas.

Reemplacé todo el código para todas las demás opciones con solo You have selected #, para no aburrir a nadie con el resto del contenido del script, pero las opciones 6me están volviendo loco.

Esto es lo que pretendo hacer, pero todavía no puedo pasar del primer punto:

  • Crear nuevo .vncarchivo
  • Agregue el cuerpo de texto del protocolo VNC estándar al archivo
  • Agregar $ComputerNamedespuésHost=
  • Lanzar el archivo

El problema es que lo siguiente no creará el archivo en absoluto; Si lo copia/pega directamente en Powershell, funciona, ¡pero no se ejecutará en un script! ¿Alguien sabe por qué podría ser eso?

$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

Respuesta1

Si se copia/pega directamente en Powershell, funciona, pero no se ejecutará en un script.

Eso suena bastante a una política de ejecución inadecuada. Puedes correr Get-ExecutionPolicypara comprobarlo. Probablemente regrese Restricted.

Para cambiar eso permanentemente, ejecute un PowerShell elevado y ejecútelo Set-ExecutionPolicy RemoteSignedy confirme con y.

Para cambiar eso temporalmente solo para la ejecución de su script, puede ejecutarlo así:

powershell -ExecutionPolicy Bypass -File .\ScriptFile.ps1

Entonces, así es como puedes ejecutar tu script desde un archivo de script. Además de eso, existe otro problema, ya mencionado por@jfrmilner. En su sexta opción, está definiendo otro bloque de script mediante llaves adicionales:

...
} '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' {
...

La definición en sí no incluirá esas líneas. Tienes dos posibilidades para solucionar este problema:

  1. Omita las llaves y, por lo tanto, no defina un bloque de script. Las líneas serán ejecutadas.
  2. Prefije el bloque de script con a .y se ejecutará:
...
} '6' {
      $ComputerName = (Read-Host "ComputerName")
      .{
        # This is a scriptblock that will directly be executed!
      }
    } 'q' {
...

Respuesta2

Lo mismo ocurre con lo que dicen @Reg Edit y @Lee-Dailey.

No podemos ver tu pantalla.

En segundo lugar, ¿por qué esperarías...?

&$commands

...¿esto funciona en un script?

$commands no es un .ps1 para ejecutar, es un bloque de secuencia de comandos en su secuencia de comandos.

Dice que está pegando en la consola powershell.exe o en ISE o VSCode, se supone que funciona porque cargó el código y lo ejecutó desde una instancia de PowerShell existente y el código se leyó en esa instancia.

Entonces, a menos que este código se guarde como commands.ps1, entonces &$commands es discutible porque el código nunca se carga en una instancia de PowerShell en ejecución o llamada.

Además, ese scriptblock realmente no es necesario en absoluto.

Entonces, prueba esto...

# 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}
}

Ejecutar ---

.\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
#>

información relacionada