Windows10 のコマンドラインで、管理者権限を持っていない通常ユーザが、 管理者権限が必要なプログラムを起動しようとすると、ID、パスワード入力が必要となります。
これは UAC と呼ばれる Windows Vista から導入されたセキュリティ機能で、悪いプログラムが勝手にシステム設定を変更したりできないような仕組みです。
しかし、管理者権限が必要なプログラムやバッチを一般ユーザから実行したい時、入力を求められるので全自動でバッチを動かしたいときに邪魔になるケースがあります。 そこで、このページではバッチから管理者権限で「パスワードを組み込んで、手動での作業を行わずに、自動的に」必要なプログラムを起動、実行するための手順を記載しています。
セキュリティ的に問題となることがありますので、常用する技術ではなく、デメリットをご理解の上で使うことが必要です。
また、バッチから管理者として実行しているのに、「要求された操作には、権限の昇格が必要です。管理者として実行してください。」とエラーメッセージが表示され、実行できないことがあります。 こういった場合でのコマンドラインでの権限変更方法についてもまとめています。
権限不足でアクセスが拒絶される時は大きく二つかと思います。
例えば管理者権限がない通常ユーザでログインし、Windows システムフォルダにファイル書き込みしようとしたときは以下のようなメッセージが表示されます。
> echo kakikomi > %windir%\test.txt
アクセスが拒否されました。
この場合はアクセスする先のフォルダ権限が足りていない場合があります。
dir /q
コマンドを使っての所有者の確認、
icacls コマンドや takeown コマンドを使ってのアクセス件を付与することが必要です。
ここでは割愛します。
管理者なのに、下のようなメッセージがでる場合があります。
管理者として実行してるのにー!という気持ちになります。
要求された操作には、権限の昇格が必要です。管理者として実行してください
以下、この場合での対処方法を記載します。
runas コマンドを使うと、実行ユーザを指定してプログラムを起動できます。
runas /user:Administrator "cmd"
これでユーザ名の権限で cmd (コマンドプロンプト)を起動できます。powershell からでも実行できます。
これで管理者権限でコマンドプロンプトが起動できます。
ただし、この状態で「netsh」コマンドなどでインターネット設定関連を変更しようとすると 権限不足と言われてしまいます。(他にもマシンの設定を変更するもので同様の権限不足が発生することも)
組織のネットワーク等で、Active Directory 認証を使ってのユーザ管理をしており、 Active Directory の管理者権限へ切り替えたときでも同じようなエラーとなります。
これは runas コマンドでの実行ユーザ切替では特権の付与が十分に与えられていないため起こります。
現在の自身の特権は whoami
コマンドを使うことで確認できます。
whoami コマンドは Windows では自身のユーザ情報を確認するコマンドです。
whoami 単独では、自身のユーザ名を確認できます。
コマンドラインで実行した例を見てみます。通常のユーザ権限から、runas コマンドでAdministrator に昇格したときの様子です。
> whoami
amaji-devterm\Administrator
> whoami /priv
PRIVILEGES INFORMATION
----------------------
特権名 説明 状態
============================= =============================================== ====
SeShutdownPrivilege システムのシャットダウン 無効
SeChangeNotifyPrivilege 走査チェックのバイパス 有効
SeUndockPrivilege ドッキング ステーションからコンピューターを削除 無効
SeIncreaseWorkingSetPrivilege プロセス ワーキング セットの増加 無効
SeTimeZonePrivilege タイム ゾーンの変更 無効
Administrator(管理者)ユーザなのに、runas コマンドで起動した Administrator は特権が少ないです。 後述していますが、ちゃんと UAC で認証して立ち上げたコマンドプロンプトで、権限を確認したものと比較してみましょう。
Windows Vista 以降の Windows OS は「ユーザーアカウント制御(User Account Control。以下UAC)機能があり、 不用意にユーザがシステム変更してしまうような、特権が必要なプログラムの呼出しを防いでくれます。
管理者権限での操作が必要な作業をしようとすると、専用の認証画面に一時的に切り替わり、利用者の手動での認証(ID、パスワード入力)が必要となります。 これは怪しい自動操作プログラムなどから、入力を受け付けないような工夫※でもあります。
長くなってしまうのでUACがどう実現されているかの詳細はここでは割愛します。 Microsoft 社が公開している isolation 0 仕様とか読むと理解がすすみます! Windows上でバックグラウンドで動作する、動的にやり取りできるサービスを作る時にも知っておく必要があったります。
以下のような操作をすると発生しますね。
UACが出てしまうと、どうしてもコマンドラインのみで操作を完了したい作業がストップしてしまいますね。 (セキュリティ的には正しいですし、通常であれば毎回認証すべきです)
runas コマンドで実行ユーザを切替し、powershell で自身のユーザからプログラムを再実行します。 poweshell の start-process 関数であれば、ログインした時と同等の特権が付与された状態となり、 実行者がユーザ自身であれば、UAC は表示されません。
runas /user:username cmd
powershell start-process cmd -verb runas
↓ 一行にするとこんな感じに。
runas /user:username "powershell start-process cmd -verb runas"
Active Directory 管理下でも同様の手順で対応可能です。
runas /user:username@ad-server.local "powershell start-process cmd -verb runas"
これを実行すれば、コマンドプロンプトからパスワードを入力を求められます。 パスワードが正しければ管理者権限で、かつ、特権が必要なコマンドが UAC 無しで実行できるようになります。
図にするとこんな感じです。
Windows で標準的に利用可能な、 powershell を使うことで、 ID、パスワードの手入力すら省略することができます。
具体的には、Windows の資格情報(Credential)を手動で作成し、資格情報を使って、新しくプログラムを起動させています。
これを使えば、バッチの中に、パスワードを組み込んで完全に自動化ができます。
もちろん、平文でのパスワードをバッチ上に書いておくことは推奨できませんので、ご利用にはご注意くださいね。
powershell のサンプルコードを下に記載しています。 これで通常ユーザが、特権付き管理者権限でコマンドプロンプトを起動できます。毎度の UAC やパスワード入力もスキップして、 特権が付与された管理者権限でcmd プログラムを起動できます。
$uid = "ユーザID"
$pw = "パスワード"
$secPw = ConvertTo-SecureString -String $pw -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $uid, $secPw
Start-Process powershell -Credential $cred -WindowStyle Minimized -ArgumentList "-noexit -command Start-Process cmd -verb runas"
上記を実行して立ち上がったコマンドプロンプトから、自身の権限を確認してみます。
> whoami
Administrator
> whoami /priv
PRIVILEGES INFORMATION
----------------------
特権名 説明 状態
========================================= ====================================================== ====
SeIncreaseQuotaPrivilege プロセスのメモリ クォータの増加 無効
SeSecurityPrivilege 監査とセキュリティ ログの管理 無効
SeTakeOwnershipPrivilege ファイルとその他のオブジェクトの所有権の取得 無効
SeLoadDriverPrivilege デバイス ドライバーのロードとアンロード 無効
SeSystemProfilePrivilege システム パフォーマンスのプロファイル 無効
SeSystemtimePrivilege システム時刻の変更 無効
SeProfileSingleProcessPrivilege 単一プロセスのプロファイル 無効
SeIncreaseBasePriorityPrivilege スケジューリング優先順位の繰り上げ 無効
SeCreatePagefilePrivilege ページ ファイルの作成 無効
SeBackupPrivilege ファイルとディレクトリのバックアップ 無効
SeRestorePrivilege ファイルとディレクトリの復元 無効
SeShutdownPrivilege システムのシャットダウン 無効
SeDebugPrivilege プログラムのデバッグ 無効
SeSystemEnvironmentPrivilege ファームウェア環境値の修正 無効
SeChangeNotifyPrivilege 走査チェックのバイパス 有効
SeRemoteShutdownPrivilege リモート コンピューターからの強制シャットダウン 無効
SeUndockPrivilege ドッキング ステーションからコンピューターを削除 無効
SeManageVolumePrivilege ボリュームの保守タスクを実行 無効
SeImpersonatePrivilege 認証後にクライアントを偽装 有効
SeCreateGlobalPrivilege グローバル オブジェクトの作成 有効
SeIncreaseWorkingSetPrivilege プロセス ワーキング セットの増加 無効
SeTimeZonePrivilege タイム ゾーンの変更 無効
SeCreateSymbolicLinkPrivilege シンボリック リンクの作成 無効
SeDelegateSessionUserImpersonatePrivilege 同じセッションで別のユーザーの偽装トークンを取得します 無効
runas コマンドで管理者権限になっただけであれば、5つしか特権がなかったですが、 こちらはちゃんと、沢山の特権が付与されています。
上記の powershell を使って新しくコマンドプロンプトを立ち上げた時、立ち上げたコンソールへのキーボード入力が上手くいかない場合がありました。
Powershell の Start-Process 経由で別のユーザ権限のコマンドプロンプト(cmd)や poewrshell を立ち上げると、
うまく標準入力ができない(キーボードからの入力ができない)ことがあります。
おそらく、新規で作成したプロセスに対して、標準入力の割当がされていないことが原因の模様。
System.Diagnostics.Process.Start() を実行してあげることで解決できるっぽいです。(未確認です)
なお、powershell のコンソールから別の powershell や cmd を起動するときは特に上記のようなトラブルは発生せず。
cmd から、powershell をワンライナーで起動して別プロセスを立ち上げるときが問題になるような気がします。
「PowerShell の Credential を使った権限昇格」の項で記載された powershell スクリプトを ワンライナーにまとめれば、powershell からでも コマンドプロンプトからでも、
+ の「ファイル名を指定して実行」からでも管理者権限で プログラムが起動できます。「一行のコマンドで特権付き管理者権限で起動を行う」の項でお話しした内容を ショートカットに書いてあげるだけです。
Administrator グループに登録している人でも、特権が必要なプログラムを実行しようとすると 通常、UAC を経由する必要があります。
しかし、Windows のタスクスケジューラに ”管理者として実行する” 設定で登録したタスクは 通常ユーザから、UAC ダイアログを出さずに管理者として実行できますので、 これを利用して、UAC を出さずにバッチ等からの起動ができます。
バッチに直接、管理者の ID や PW を埋め込むよりはセキュリティ的には安全ですね。
コントロールパネルからタスクを登録してもOKですが、 ここではコマンドラインからタスクを登録してみます。
管理者権限でタスクスケジューラに必要なコマンドを登録をしてみましょう。 Windows のレジストリを起動するために管理者権限(UACでの認証)が必要なので、 regedit.exe を指定してみます。
schtasks /CREATE /TN testdesu /TR "C:\Windows\regedit.exe" /SC ONCE /ST 00:00 /RL highest /F
schtasks コマンドのオプションは以下の通りです。
タスク名はテスト用に適当な「testdesu」を登録しておきます。
ここで、(/SCオプション)タスク名には「ONCE」を指定しています。ONCEは「タスクが指定した日時に 1開実行される」という実行方法です。
また、(/STオプション)実行する時刻は HH:mm の24時間形式で指定しますが、ここでは 00:00 を指定します。
実行し、登録に成功すると下記のメッセージが表示されます。
警告: /ST が現時刻よりも早いため、タスクは実行されない可能性があります。
成功: スケジュール タスク "testdesu" は正しく作成されました。
下のコマンドで登録状況を確認できます。
schtasks /Query /v /tn testdesu
続いて、登録した「testdeus」タスクをコマンドで実行してみます。
schtasks /RUN /TN testdesu
通常、UAC が必要となるプログラム(例:regeditなど)がそのまま起動できます。
以下で削除可能です。
schtasks /DELETE /TN testdesu
確認されますので、 「y」を入力し削除が完了します。
警告: タスク "testdesu" を削除しますか (Y/N) ? y
成功: スケジュール タスク "testdesu" は正しく削除されました。
ショートカット作ってあげれば、 後はマウスからクリックするだけで簡単に作ったタスクを起動できます。
具体的には「schtasks /RUN /TN testdesu
」を起動するショートカットを用意してあげれば OK です。
UAC はセキュリティ保護のためのしくみであり、意図しないプログラムが動作することを防ぐ効果があります。
便利だからと言って、むやみに UAC を経由せずに特権で実行するようなバッチを運用することはセキュリティ上問題があるので ご注意くださいね。(あたりまえですが、私は責任とれませんよー。)
更新日 | 更新内容 |
---|---|
更新なし |
コメント、ありがとうございます。
ごめんなさい。エラーでうまく送信できませんでした。ご迷惑をおかけします。しばらくおいてから再度送信を試していただくか、以下から DM などでご連絡頂ければと思います。
Twitter:@NodachiSoft_jpお名前:以下の内容でコメントを送信します。よろしければ、「送信」を押してください。修正する場合は「戻る」を押してください
お名前: