動的PowerShellを使用して現在のユーザーを取得する方法

Windowsで作業する際、いずれかの時点でコンピュータに現在ログインしているユーザーアカウントを確認する必要があるかもしれません。幸いなことに、PowerShellを使用してローカルまたはリモートコンピュータ上の現在のユーザーを取得することができます。

Active Directoryに侵害されたパスワードはありますか?Specops Password Auditor Freeで確認してください。

このチュートリアルでは、PowerShellを使用してコンピュータ上の現在のユーザーを取得するさまざまな方法を学びます。学習するメソッドには、ネイティブコマンド、.NETクラス、およびWindows Management Instrumentation(WMI)固有のcmdletが含まれます。

コンピュータ上に潜んでいる人物を知りたいですか?それでは始めましょう!

前提条件

このチュートリアルでは、例に従って学習するのが最適です。そのためには、Windows 10、Windows Server 2012など、最新バージョンのWindowsが実行されているコンピュータが必要です。

このチュートリアルでは、DC1という名前のWindows Server 2019を実行しているコンピュータが使用されます。

なぜPowerShellを使用してコンピュータにログインしている現在のユーザーを取得するのですか?

正直に言うと、PowerShellを使わずにコンピュータにログインしている現在のユーザーを取得する方法があります。結局のところ、システム管理者はPowerShellより前にもそのような方法を持っていたはずですよね?もしそうなら、なぜPowerShellを使うのですか?

同じタスクをPowerShellで行うことの利点は、結果をオブジェクトとして扱えることです。例えば、ユーザーの資格情報をプロンプトで求めるスクリプトを実行する場合、PowerShellはプログラムでユーザー名を入力し、パスワードを手動で入力する必要があるだけです。

もう1つの実際の例は、サーバーに現在ログインしているユーザーのリストをファイルにエクスポートすることです。これはPowerShellを使用して現在のユーザーを取得し、その結果をCSVHTML、またはXMLファイルにエクスポートすることで実現されます。その後、さまざまな自動化ワークフローがこの出力を使用できます。

現在のユーザーを取得するためにPowerShellを使用する理由は数千ありますが、最終的な目的はすべてあなたの要件に帰着します。このチュートリアルでは、その目標を達成するさまざまな方法を教えます。

Win32_ComputerSystemクラスのクエリ

始めましょう。PowerShellのネイティブなコマンドレットは、Get-WMIObjectGet-CimInstanceと呼ばれています。これらのコマンドレットを使用すると、ローカルまたはリモートコンピューターで、現在ログオンしているユーザーを含む情報をクエリできます

Get-WMIObjectは古い(非推奨)コマンドレットであり、Windows PowerShell 5.1までしか利用できません。対照的に、Get-CIMInstanceは新しい、より安全なコマンドレットであり、最新のPowerShellバージョンまで利用可能です

詳細については、Get-CIMInstance Vs. Get-WMIObject: What’s The Difference?をご覧ください。

PowerShellを使用して現在のユーザーを取得するには、Win32_ComputerSystemクラスを対象とするコマンドレットを呼び出します。Win32_ComputerSystemクラスには、Usernameプロパティを含むさまざまなプロパティがあります。これを行うには、PowerShellウィンドウを開いて、以下のコマンドを実行します。

# Get-WMIObjectコマンドレットを使用し、Usernameプロパティのみを返す
(Get-WMIObject -ClassName Win32_ComputerSystem).Username

# Get-CimInstanceコマンドレットを使用し、Usernameプロパティのみを返す
(Get-CimInstance -ClassName Win32_ComputerSystem).Username

注意: Win32_ComputerSystemクラスをクエリすると、直接コンピュータにログオンしているユーザー(コンソールセッション)のみが返されます。ユーザーがリモートでログオンしている場合(たとえば、リモートデスクトップ)、ユーザー名は空白になります。

両方のコマンドは同じ結果を返します。現在のユーザーがドメインユーザーアカウントの場合、コマンドはドメインとユーザー名(ドメイン\ユーザー名)を返します。しかし、ローカルユーザーアカウントの場合、出力はコンピューター\ユーザー名になります。

Querying WMI in PowerShell to Get Current Users

Get-WMIObjectGet-CimInstanceには、クエリするコンピューターの名前を受け入れる-computerNameというパラメーターがあります。このパラメーターを使用すると、ネットワーク内のリモートマシンから同じ情報をクエリできます。

しかし、ドメインを除いたユーザー名のみを取得する必要がある場合、split()メソッドを使用して出力を分割することが解決策です。そのために、PowerShellで以下のコマンドを実行します。

# 以下のコマンドは、バックスラッシュ '\' 文字を区切り文字として使用して、ユーザー名プロパティを2つに分割します。
# 最後の [1] 部分は、コマンドにインデックス1の結果のみを返すように指示します。
# インデックスは0から始まるため、インデックス1を指定すると2番目の位置の結果が表示されます。
((Get-WMIObject -ClassName Win32_ComputerSystem).Username).Split('\')[1]

その結果、PowerShellはスクリーンショットのようにユーザー部分のみを返します。

Splitting the username property

Windows環境変数の読み取り

別の方法は、PowerShell を使用してコンピューター上の現在のユーザーを取得することです。これは、環境変数から値を取得することで行います。環境変数は、現在のユーザーのユーザー名など、オペレーティングシステムのデータを表します。

環境変数とやり取りする方法は3つあります。選んだ方法に関係なく、同じ結果が返されます。

Env PowerShell ドライブ

PowerShell は環境変数をキャッシュし、Env: ドライブと呼ばれるPowerShell ドライブ (PSDrive)を介してそれらを利用できるようにします。PSDrive はコンピューター上のドライブのようにアクセスできるデータの場所です (例:C:)、ただし PowerShell 内でのみアクセスできます。

PowerShellは、PowerShellセッションを開くとすぐにEnv:ドライブを自動的に作成します。そしてEnv:はドライブなので、ファイルシステムのドライブやフォルダーの内容をリストする方法と同様に、Get-ChildItemコマンドレットを呼び出すことでその内容を取得できます。

PowerShellでEnv:ドライブを使用して、現在のユーザーを取得するには、以下のコマンドを実行します。

Get-ChildItem Env:\USERNAME

以下のスクリーンショットは、期待される結果を示しています。コマンドはUSERNAMEアイテムとその対応する値、つまり現在ログオンしているユーザーを返すことがわかります。

Getting the Env:\USERNAME item

ユーザー名の値のみを返すには、以下のようにコマンドを変更してPowerShellで再実行します。

(Get-ChildItem Env:\USERNAME).Value

以下のように、コマンドはユーザー名の値のみを文字列として返します。

Getting the Env:\USERNAME value

$env変数

環境変数にアクセスする方法の一つは、PSDriveとして環境変数にアクセスすることです。つまり、以下の構文を使用して環境変数を参照できます。

# $記号は変数を示します
# envはEnvドライブです
# <変数>は取得したい変数名です
$env:<variable>

上記の構文に基づいて、PowerShellで以下のコマンドを実行して現在のユーザーを取得します。

$env:username

以下のスクリーンショットに示すように、コマンドはユーザー名の値を返します。

Getting the username variable value

.NET Environmentクラス

PowerShellはオブジェクト指向の言語であり、シェルです。基本的に、PowerShell内で作業するすべてはオブジェクトです。コマンドを実行すると、出力はオブジェクトです。変数を宣言した場合、その変数自体がオブジェクトです。そのような感じです。

これらのオブジェクトには、データ型を定義する構造があります。これらの設計図は.NETクラスまたは単にクラスと呼ばれます。

環境変数に関しては、それに関連付けられたクラスはEnvironmentクラスです。したがって、PowerShellでEnvironmentクラスをどのように使用して現在のユーザーを取得するかについては、次のようにしてください。

$env変数のように、EnvironmentクラスにはUsernameプロパティがあり、その値は現在のユーザーのユーザー名です。ユーザー名プロパティの値を取得するには、PowerShellで以下のコマンドを実行します。

[System.Environment]::UserName
Getting the environment username property value

Usernameプロパティ以外にも、Environmentクラスには環境変数の値を取得するメソッドがあります。そのメソッドの名前はGetEnvironmentVariableです。

このメソッドを使用して現在のユーザーを取得するには、以下のコマンドを実行します。

[System.Environment]::GetEnvironmentVariable('username')
Getting the environment variable value

.NET WindowsIdentityクラスを使用する

WindowsIdentityクラスは、PowerShellで現在のユーザーを取得するために使用できる別の.NETクラスです。このクラスには、GetCurrentNameというメソッドがあり、現在のWindowsユーザーを表すオブジェクトを返します。

現在のユーザーの詳細を取得するには、以下のコマンドを実行してください。

[System.Security.Principal.WindowsIdentity]::GetCurrent()

以下のように、このコマンドは現在のユーザーオブジェクトのプロパティを返します。その中には、Nameプロパティも含まれます。 Nameプロパティの値の形式は、ドメイン\ユーザーの規則に従います。

Getting the current Windows user

ユーザー名の部分のみを返すには、前のコマンドを変更してNameプロパティのみを選択し、文字列の分割技術を適用します。そのためには、以下のコマンドをコピーしてPowerShellで実行してください。

([System.Security.Principal.WindowsIdentity]::GetCurrent().Name).Split('\')[1]
Returning only the username part

whoamiコマンドを使用する

現在のユーザーをすばやく取得するためのもう1つの便利なコマンドがwhoamiコマンドです。このコマンドは、%WINDIR%\System32フォルダーにwhoami.exeというファイル名で見つけることができる実行可能ファイルです。

現在のユーザーのユーザー名を取得するには、以下のコマンドを実行してください。

whoami

そのコマンドは、ドメイン ユーザー名の形式で結果を返します。

Getting the username using whoami

ユーザー名をドメインなしで取得するには、以下のコマンドを実行して、以前に学んだ文字列分割技術を適用します。

(whoami).Split('\')[1]
Getting the username without the domain

また、whoamiコマンドを使用すると、現在のユーザーの完全修飾名(FQDN)とユーザープリンシパル名(UPN)も取得できます。このコマンドの出力は、ユーザー名を超えた現在のユーザーの ID を取得するスクリプトを実行する場合に役立ちます。PowerShellで以下のコマンドを実行して、現在のユーザーのFQDNとUPNを取得します。

# 現在のユーザーのFQDNを取得
whoami /fqdn

# 現在のユーザーのUPNを取得
whoami /upn
Getting the current user’s FQDN and UPN

注意:FQDNとUPNの値は、現在ログインしているユーザーがドメインユーザーの場合にのみ利用可能です。これらの値をローカルユーザーに取得しようとすると、以下のようにエラーが返されます。

Error getting the UPN and FQDN of a non-domain user account

queryコマンドを使用する

システム管理者やドメインユーザーの場合、おそらくリモートデスクトッププロトコル(RDP)を介して少なくとも一度はリモートマシンにログインしたことがあるでしょう。リソースの管理やアプリケーションの使用など、理由はさまざまですが、現在誰がログインしてシステムリソースを使用しているかを知りたいと思うでしょう。

幸いなことに、Windowsにはqueryという組み込みのコマンドラインツールがあり、コンピューターに現在ログオンしているすべてのユーザーをリストアップすることができます。このコマンドは、ユーザーがリモートデスクトップセッションを介してログオンしたか、コンピューターにローカルでログオンしたかも表示します。

queryコマンドには、ログオンしているユーザーを取得するための2つのパラメーターがあります。それはsessionuserです。sessionパラメーターはコンピューターセッションをリストし、userパラメーターはユーザーとそのセッションをリストします。

query sessionコマンドにはqwinstaというエイリアスがあり、query userのコマンドエイリアスはquserです。

例えば、以下のコマンドを実行してDC1のセッションをリストアップします。

# DC1でのセッションをクエリ
qwinsta /server:dc1

以下のスクリーンショットは、コマンドの出力を示しています。この例では、2人のユーザーがDC1コンピューターにログオンしています。1人はコンソールセッションで、もう1人はRDP経由でログオンしています。ご覧の通り、qwinstaは、非ユーザーセッションも含めてすべてのセッションを返します。

Querying sessions

/server:<computer>引数なしでqwinstaまたはquserを単体で実行すると、どちらのコマンドもデフォルトでローカルコンピューターをクエリします。

次に、既存のログオンセッションを持つすべてのユーザーをリストアップするには、以下のuserコマンドを実行します。

# DC1上のユーザーをクエリする
quser /server:dc1

コマンドを実行した後、quserはセッションとユーザーをqwinstaコマンドのように返します。ただし、今回は空のセッションはありません。

さらに、IDLE TIME列とLOGON TIME列の2つの追加列があります。これらは、ユーザーのアイドル時間とログオンタイムスタンプを示します。

Querying users

結局のところ、qwinstaquserの結果を比較すると、現在のユーザーを取得するにはPowerShellでquserがより適切なコマンドです。

Active Directoryに侵害されたパスワードがありますか?無料のSpecops Password Auditor Freeで確認してください。

Conclusion

現在のユーザーを取得するためにPowerShellで多くの方法がありますが、最適な方法は取得したい結果とその使用方法に依存します。

ネイティブのWMI関連のcmdletとqueryコマンドを使用すると、ローカルまたはリモートコンピュータ上のログインユーザーを取得できます。.NETクラスと環境変数を使用すると同じ結果を素早く取得できますが、これはローカルコンピュータのみです。

スクリプトを実行するか、結果を手動で画面に表示するかに関わらず、PowerShellを使用して現在のユーザーを取得するための要件に合ったメソッドがあります。次は何でしょうか?おそらく、queryコマンドの結果を解析し、PowerShellオブジェクトに変換し、関数RegExを使用して学ぶことができますか?

Source:
https://adamtheautomator.com/powershell-get-current-user/