为什么这个 New-Item 命令在 powershell 中有效,但在 ps1 脚本中无效?

为什么这个 New-Item 命令在 powershell 中有效,但在 ps1 脚本中无效?

完全卡在这里,不知道该怎么办:我有一个多选交互式 Powershell 脚本,正在为操作人员整理,以便他们每次想要在远程计算机上执行快速任务时都可以节省几分钟的时间。

我已经用 替换了所有其他选择的所有代码You have selected #,因此我不会让任何人对其余的脚本内容感到厌烦,但是选择6让我发疯。

这就是我想要实现的目标,但目前还无法超越第一个要点:

  • 创建新.vnc文件
  • 将标准 VNC 协议文本主体添加到文件
  • 添加$ComputerNameHost=
  • 启动文件

问题是下面的代码根本无法创建文件;如果直接复制/粘贴到 Powershell 中,它可以工作,但它无法在脚本中运行!有人知道这是为什么吗?

$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

答案1

如果直接复制/粘贴到 Powershell 中,它可以工作,但不会在脚本中运行。

这听起来很像一个不合适的执行策略。您可以运行Get-ExecutionPolicy来检查一下。它可能会返回Restricted

要永久改变这一点,请运行提升的 PowerShell 并执行Set-ExecutionPolicy RemoteSigned并确认y

如果要暂时更改该设置以执行脚本,可以像这样运行它:

powershell -ExecutionPolicy Bypass -File .\ScriptFile.ps1

这就是你如何从脚本文件运行脚本的方法。除此之外,还有另一个问题,前面已经提到过@jfrmilner。在第 6 个选项中,您通过附加花括号定义另一个脚本块:

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

定义本身不会运行这些行。有两种方法可以解决此问题:

  1. 省略花括号,这样就不定义脚本块。这些行将被执行。
  2. 在脚本块前面加上 a.它将会被执行:
...
} '6' {
      $ComputerName = (Read-Host "ComputerName")
      .{
        # This is a scriptblock that will directly be executed!
      }
    } 'q' {
...

答案2

同意@Reg Edit 和@Lee-Dailey 的说法。

我们看不到您的屏幕。

其次,你为什么会期望……

&$commands

...这可以在脚本中工作吗?

$commands 不是要执行的 .ps1,它是脚本中的脚本块。

您说您正在粘贴 powershell.exe 控制台或 ISE 或 VSCode,它应该可以工作,因为您加载了代码并从现有的 PowerShell 实例运行它,并且该代码是在该实例中读取的。

因此,除非将此代码保存为 command.ps1,否则 &$commands 毫无意义,因为该代码从未在正在运行或调用的 PowerShell 实例中加载。

此外,该脚本块实际上根本不需要。

因此,尝试一下这个...

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

执行 - -

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

相关内容