min117の日記

初期desireもち。趣味Mac,メインFedora,仕事xp。

Windows10 バッチファイル内でPowerShellコマンドを管理者権限で実行する

Windows10に入っている不要なアプリダブルクリック一発でアンインストールしたい。バッチファイルからPowerShell呼べば可能。ただしバッチを管理者実行しないといけない。

 

 

 

できた。

doPS.bat

f:id:min117:20180503113430p:plain

Windows7で作ったが、Win10でも実行を確認済み。

※ ソースのテキストは末尾にも記載。

f:id:min117:20180503113907p:plain

 

<解説>

2行目、22行目(バッチとPowerShellの混在)

このサイト参照。とても分かりやすい。

f:id:min117:20180503114237p:plain

バッチファイル(.bat)としてもPowerShellスクリプト(.ps1)としても動作するスクリプトが書ける。ものすごい便利。

www.pg-fl.jp

ちなみにバッチファイル(.bat)としてもWindows Script Host(.vbs)としても動作するスクリプトの書き方はこちら。

min117.hatenablog.com

 

5行目(バッチの管理者実行)

このサイトそのまま。

NET SESSIONを使って管理者権限を判断したうえでラベル「RESTART」に飛ばして再実行させているのがとてつもなく上手い。かなりバッチファイルに慣れた技術者だろう。すごい。

f:id:min117:20180503120502p:plain

vogel.at.webry.info

※ バッチファイルの管理者実行といえば「OPENFILES」コマンドを使うものだと思っていたが「NET SESSION」でも可能とは。勉強になる。

 

15行目 iex

 iexPowerShellのコマンド「 Invoke-Expression 」の別名(エイリアス)。

Invoke-Expression "c:\my scripts\test script.ps1"

 のようにすれば、「test(半角スペース)script.ps1」を実行できる。

 

15行目 gc

 gc PowerShellのコマンド「 Get-Content 」の別名(エイリアス

gc test.txt

cat test.txtLinuxbash)と同じ

type test.txtWindowsバッチ)と同じ と思えばよい。

 

15行目 (gc \"%THIS_PATH:`=``%\")

 gc でファイルの内容を取得している。

 

15行目 -join

 -joinPowerShell演算子で「配列を特定の文字列を使って繋いで一つの文字列にする」

 

 

以下バッチファイルのソース

doPS.bat


@(echo '> NUL
echo off)

REM 管理者権限か確認
NET SESSION > NUL 2>&1

REM 管理者でなければ -ExecutionPolicy してから再起実行(RESTART)
IF %ERRORLEVEL% neq 0 goto RESTART

REM 管理者権限なら PS を呼んで★を実行する
setlocal enableextensions
set "THIS_PATH=%~f0"
set "PARAM_1=%~1"
PowerShell.exe -Command "iex -Command ((gc \"%THIS_PATH:`=``%\") -join \"`n\")"
PAUSE
exit /b %errorlevel%

:RESTART
powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process %~f0 -Verb runas"
exit
') | sv -Name TempVar

# ★ここから先に PowerShellスクリプトを記述する(コメントもREMでなく#になる)
$currentTime = [System.DateTime]::Now
echo "ファイル名は $env:THIS_PATH"
echo "パラメータは $env:PARAM_1"
echo "$currentTime"

echo Windows10の不要なアプリを削除します
Get-AppxPackage Microsoft.ZuneMusic | Remove-AppxPackage

 

# ################## PowerShell
#
# iex ←は↓のエイリアス
# Invoke-Expression
#
# Invoke-Expression コマンドレットの使用
# Windows PowerShell スクリプトの実行
# Invoke-Expression コマンドレットを使用すると、Windows PowerShell からスクリプトを実行できます。
# たとえば、次のコマンドでスクリプト C:\Scripts\Test.ps1 が実行されます。
#
# Invoke-Expression c:\scripts\test.ps1
#
# または、アンパサンド (&) を使用して、スクリプトを実行することを示すこともできます。
# & c:\scripts\test.ps1
#
# または、さらに簡単に、スクリプトのパスを入力するだけでも実行できます。
# c:\scripts\test.ps1
#
# いずれの場合でも、パスにスペースが含まれるときは二重引用符でパス全体を囲む必要があります。
# Invoke-Expression "c:\my scripts\test script.ps1"
#
# ##################
# gc Get-Content
# ↑Linuxのcatと同じ
# ↑Windowsのtypeと同じ
#
# ##################
# エスケープ・シーケンス概要
# `b バックスペース
# `n 改行
# `r キャリッジ・リターン
# `t タブ
# PowerShellの文字列における主なエスケープ・シーケンス
# 「`(バッククォート)」記号と1文字の英字で特殊文字を表現する。
# 多くの言語ではエスケープのために「\」記号を利用しているが、
# Windows OSではフォルダの区切り文字として「\」が用いられていることから、あえてバッククォート記号がエスケープ文字として採用されたようである。
#  これらエスケープ・シーケンスも、シングルクォートの中では認識されないので、要注意である。
# PS > Write-Output "私
#
# ##################
# PowerShell 2.0では新しい演算子-splitと-joinがサポートされました。
# -splitは「文字列を特定の文字で切り分けて配列を作る」演算子
# -join演算子は「配列を特定の文字列を使って繋いで一つの文字列にする」演算子です。
#
# 使い方です
#
# $a="a,b,c,d,e" -split ","
# $a[1]
# これは-split演算子を使って、a,b,c,d,eという文字列を、,(カンマ)で切り分けて配列にし、2つ目の要素を取り出す例です。結果は次のようになります。
# b
#
# 配列は-joinを使って一つの文字列にすることができます。先ほど作った配列を&という文字で繋げるには次のようにします。
#
# $a -join "&"
# 結果は以下のようになります。
#
# a&b&c&d&e
# このように、PowerShellでもVBScriptのSplit関数やJoin関数を使った場合と同様の文字列配列操作が可能になりました。
#
# なお、PowerShell 1.0ではこのようにします。
#
# -split演算子の代わり。string型のインスタンスに対し、Splitメソッドを実行する。
#
# $b="a,b,c,d,e".Split(",")
# -join演算子の代わり。stringクラスのスタティックメソッドJoin()を使用。
#
# [string]::Join("&",$b)
#
# ##################
#
# PowerShellから環境変数を利用するには、「Env:環境変数名」を利用する。
# 環境変数を扱うには、以下を利用する。
#
#  1.PowerShellプロバイダ(PSプロバイダ)のEnvironment
#   →PSプロバイダのEnvironmentは、環境変数のデータを扱う。
#
#  2.PowerShellドライブ(PSドライブ)のEnv
#   →環境変数を扱うドライブレターとして「Env」が用意されている。
#
# 例1)環境変数の値を確認する。
#
# PS C:\> $Env:Temp
# Z:Temp
#
# ここでは、Envの前に変数であることを示す「$」を付ける必要がある。
# $Envは、PowerShellで予約されている環境変数参照用の変数である。
# 「$」をつけずに実行すると、以下のようにエラーが発生する。
#
# PS C:\> Env:Temp