PowerShellスクリプト(ps1)を実行しやすくする


(2023/10/11 ページ構成を手直し)

PowerShellスクリプト(ps1)に対して、ファイルをドラッグ&ドロップしてもファイルを認識して実行してくれない。

また、そもそもPowerShellスクリプトを実行しようとしても、下記のエラーで実行ができない。

PS C:\Users\osakanataro\Documents\powershell> .\powershelltest.ps1
スクリプトの実行がシステムで無効になっているため、ファイル C:\Users\osakanataro\Documents\powershell\powershelltest.ps1 を読み込めません。詳細については、「get-help about_signing」と入力してヘルプを参照してください。
発生場所 行:1 文字:25
+ .\powershelltest.ps1 <<<<
    + CategoryInfo          : NotSpecified: (:) []、PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

PS C:\Users\osakanataro\Documents\powershell> 

回避方法として、バッチファイルの中からPowerShellを起動する、というものが知られている。

具体的には以下の様なバッチファイルを作って、バッチファイルをクリックする、というものになる。

@echo off
rem PowerShellスクリプトの実行が禁止されている場合に
rem このバッチファイルを管理者権限で動作させると
rem PowerShellスクリプトが実行できます。

powershell -sta -ExecutionPolicy Unrestricted -File %0\..\powershelltest.ps1 %*

この場合、PowerShellスクリプトのファイルと、バッチファイルの2つを同時に配布しなければならない、という問題がある。

これを解消するために、バッチファイルの中にPowerShellスクリプトの記述も含めてしまおう、という技がある。

@echo off
powershell -sta -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 2})-join\"`n\");&$s" %*&goto:eof
# こんな感じで書く
$PSVersionTable
などPowerShellスクリプトの内容を記載

やってることは、バッチファイルからPowerShellを起動したら、そのPowerShellは、いま起動に使ったバッチファイルの2行目の次からスクリプトを読み出しを開始しバッチファイルの最後まで読み込んだあと、PowerShellスクリプトとして実行を開始する、というもの

これによって、バッチファイル1個だけでPowerShellを実行できるようになる。

ただ、この技を使うとLinux/MacOSXなどの他OSのPowerShell環境で動作させにくくなる、という弊害もあるので、Windows環境のみで使う場合にとどめておくと良い。

別解として下記もあると教えていただきました。

@ set args=%*
@ powershell "iex( (@('','','')+(cat '%~f0'|select -skip 3))-join[char]10)"
@ exit /b %ERRORLEVEL%

ここから下は以前の記述


回避方法は下記の2つを行う、ということ

・バッチファイル経由でPowerShellを起動する
・うまく行かない場合は、管理者権限でバッチファイルを起動する

今回使用したバッチファイルは下記の内容とした

@echo off
rem PowerShellスクリプトの実行が禁止されている場合に
rem このバッチファイルを管理者権限で動作させると
rem PowerShellスクリプトが実行できます。

powershell -sta -ExecutionPolicy Unrestricted -File %0\..\powershelltest.ps1 %*

なお、powershell起動時に「-sta」オプションをつけているのは、powershellからフォームダイアログを開こうとすると、下記のエラーがでてしまうことを回避するためです。

なお、詳細を開くと下記の情報が出力されている

Just-In-Time (JIT) デバッグを呼び出すための詳細については、
ダイアログ ボックスではなく、このメッセージの最後を参照してください。

************** 例外テキスト **************
System.InvalidOperationException: DragDrop 登録は成功しませんでした。 ---> System.Threading.ThreadStateException: OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。Main 関数に STAThreadAttribute が設定されていることを確認してください。
   場所 System.Windows.Forms.Control.SetAcceptDrops(Boolean accept)
   --- 内部例外スタック トレースの終わり ---
   場所 System.Windows.Forms.Control.SetAcceptDrops(Boolean accept)
   場所 System.Windows.Forms.Control.OnHandleCreated(EventArgs e)
   場所 System.Windows.Forms.ListBox.OnHandleCreated(EventArgs e)
   場所 System.Windows.Forms.Control.WmCreate(Message& m)
   場所 System.Windows.Forms.Control.WndProc(Message& m)
   場所 System.Windows.Forms.ListBox.WndProc(Message& m)
   場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   場所 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** 読み込まれたアセンブリ **************
mscorlib
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5485 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
----------------------------------------
Microsoft.PowerShell.ConsoleHost
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7600.16385
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.ConsoleHost/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.ConsoleHost.dll
----------------------------------------
System
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.8686 (QFE.050727-8600)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Management.Automation
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Management.Automation/1.0.0.0__31bf3856ad364e35/System.Management.Automation.dll
----------------------------------------
Microsoft.PowerShell.Commands.Diagnostics
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Diagnostics/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Diagnostics.dll
----------------------------------------
System.Core
    アセンブリ バージョン: 3.5.0.0
    Win32 バージョン: 3.5.30729.5420 built by: Win7SP1
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Core/3.5.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Configuration.Install
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5483 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Configuration.Install/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.Install.dll
----------------------------------------
Microsoft.WSMan.Management
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.WSMan.Management/1.0.0.0__31bf3856ad364e35/Microsoft.WSMan.Management.dll
----------------------------------------
System.Transactions
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5483 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_64/System.Transactions/2.0.0.0__b77a5c561934e089/System.Transactions.dll
----------------------------------------
Microsoft.PowerShell.Commands.Utility
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Utility/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Utility.dll
----------------------------------------
Microsoft.PowerShell.Commands.Management
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Management/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Management.dll
----------------------------------------
Microsoft.PowerShell.Security
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Security/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Security.dll
----------------------------------------
Microsoft.PowerShell.ConsoleHost.resources
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7600.16385
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.ConsoleHost.resources/1.0.0.0_ja_31bf3856ad364e35/Microsoft.PowerShell.ConsoleHost.resources.dll
----------------------------------------
System.Xml
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5494 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Management
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5483 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Management/2.0.0.0__b03f5f7f11d50a3a/System.Management.dll
----------------------------------------
System.DirectoryServices
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5483 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.DirectoryServices/2.0.0.0__b03f5f7f11d50a3a/System.DirectoryServices.dll
----------------------------------------
System.Management.Automation.resources
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7600.16385
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Management.Automation.resources/1.0.0.0_ja_31bf3856ad364e35/System.Management.Automation.resources.dll
----------------------------------------
Microsoft.WSMan.Management.resources
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.WSMan.Management.resources/1.0.0.0_ja_31bf3856ad364e35/Microsoft.WSMan.Management.resources.dll
----------------------------------------
mscorlib.resources
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5485 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
----------------------------------------
Microsoft.PowerShell.Security.resources
    アセンブリ バージョン: 1.0.0.0
    Win32 バージョン: 6.1.7601.17514
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Security.resources/1.0.0.0_ja_31bf3856ad364e35/Microsoft.PowerShell.Security.resources.dll
----------------------------------------
System.Data
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.8692 (QFE.050727-8600)
    コードベース: file:///C:/Windows/assembly/GAC_64/System.Data/2.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Windows.Forms
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5491 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5495 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
Accessibility
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5483 (Win7SP1GDR.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/Accessibility/2.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
System.Windows.Forms.resources
    アセンブリ バージョン: 2.0.0.0
    Win32 バージョン: 2.0.50727.5420 (Win7SP1.050727-5400)
    コードベース: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms.resources/2.0.0.0_ja_b77a5c561934e089/System.Windows.Forms.resources.dll
----------------------------------------

************** JIT デバッグ **************
Just-In-Time (JIT) デバッグを有効にするには、このアプリケーション、
またはコンピュータ (machine.config) の構成ファイルの jitDebugging 
値を system.windows.forms セクションで設定しなければなりません。
アプリケーションはまた、デバッグを有効にしてコンパイルされなければ
なりません。

例:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

JIT デバッグが有効なときは、このダイアログ ボックスで処理するよりも、
ハンドルされていない例外はすべてコンピュータに登録された
JIT デバッガに設定されなければなりません。

2021/05/12追記

これをさらにすすめて、バッチファイル内にPowerShellスクリプトを書いてしまう、という技もあることを知った。

powershell -sta -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof
# こんな感じで書く
$PSVersionTable
~

注意点として、powershellを起動するより前に日本語を書いてはいけない、ということ

これはDOSプロンプトとPowerShellとで日本語の取り扱いが異なるため発生しているので、DOS側では日本語を取り扱わず、PowerShellが起動した後には使う、というようにしなければならない

また、@echo offを入れたい、という場合は下記の様にreadcount の後の数字を増やして対応する。(指定行数より後をPowerShellスクリプトとして読み込み、という命令)

@echo off
powershell -sta -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 2})-join\"`n\");&$s" %*&goto:eof
# こんな感じで書く
$PSVersionTable
~

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください