この New-Item コマンドは PowerShell 内では機能するのに、ps1 スクリプト内では機能しないのはなぜですか?

この New-Item コマンドは PowerShell 内では機能するのに、ps1 スクリプト内では機能しないのはなぜですか?

完全に行き詰まっていて、何をすればいいのかわかりません。私は、オペレーション用に複数選択のインタラクティブな Powershell スクリプトを作成しており、これにより、リモート コンピューターで簡単なタスクを実行したいときに、数分を節約できます。

他のすべての選択肢のコードすべてを に置き換えたのでYou have selected #、スクリプトの残りの内容で誰も退屈することはありませんが、選択肢の多さに6気が狂いそうです。

これが私が目指していることですが、まだ最初の箇条書きを超えることができません。

  • 新しい.vncファイルを作成
  • ファイルに標準のVNCプロトコルのテキスト本体を追加します
  • $ComputerName後に追加Host=
  • ファイルを起動する

問題は、以下ではファイルがまったく作成されないことです。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

これでスクリプトファイルからスクリプトを実行することができます。それに加えて、すでに述べたように別の問題があります。フォロー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' {
...

定義自体はこれらの行を実行しません。この問題を解決するには 2 つの方法があります。

  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 インスタンスから実行し、そのインスタンスでコードが読み取られたため、機能するはずです。

したがって、このコードが commands.ps1 として保存されない限り、実行中または呼び出された PowerShell インスタンスにコードが読み込まれることはなく、&$commands は意味がありません。

また、そのスクリプトブロックは実際にはまったく必要ありません。

それで、これを試してみてください...

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

関連情報