ローカルマシンでPowershell Get Activeログインユーザー


3

私は現在アクティブなセッションを持っているユーザーにログインしようとしています。

タスクマネージャでは、2つのユーザーセッションがあり、1つがアクティブであることがリストから明確にわかります。

私はPowershellで同じことを質問したいです。 利用可能なコマンドをいくつか試しました Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique 私が見ることができるよりもはるかに多くのユーザーをリストしています[ドメイン参加コンピューター]

タスクマネージャとまったく同じ結果が得られるクエリを探しています。 enter image description here


どうですか? query user
duenni

@ duenniは正しい方法のようです。とにかく解析して取得する Active users。文字列出力のようです
Reddy

多分これはあなたを助けることができる superuser.com/q/587737/378809
duenni

私の知る限りでは、PowerShellを使ったネイティブな方法はありません。見る Powershellは 'query user'から値を取得し、ヘッダなどは取得しません
Ƭᴇcʜιᴇ007

@MagicallyDelicous、私は実際にリモートPowerShellを使用してリモートマシンでいくつかのスクリプトを実行しようとしています。アクティブなユーザーがいない場合、私はマシンを再起動しようとしています。
Reddy

回答:


3

の問題 Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique 最後にコンピュータを再起動してから閉じられたセッションも含め、すべてのセッションが表示されます。セッションをポーリングする最も簡単な方法は、残念ながら古い実行可能なquery.exeを使うことです。

ちょっとした正規表現を使ってquery.exeの出力をオブジェクトに変換することができます。

$Computer = $env:COMPUTERNAME
$Users = query user /server:$Computer 2>&1

$Users = $Users | ForEach-Object {
    (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1  none  $2' -replace "\s{2,}", "," -replace "none", $null))
} | ConvertFrom-Csv

foreach ($User in $Users)
{
    [PSCustomObject]@{
        ComputerName = $Computer
        Username = $User.USERNAME
        SessionState = $User.STATE.Replace("Disc", "Disconnected")
        SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
    } 
}

これにより、次のような出力が得られます。

ComputerName Username SessionState SessionType
------------ -------- ------------ -----------
BSMITH-LT    bobsm    Active       console    

関数にもっと深く取り込む:

function Convert-QueryToObjects
{
    [CmdletBinding()]
    [Alias('QueryToObject')]
    [OutputType([PSCustomObject])]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0)]
        [Alias('ComputerName', 'Computer')]
        [string]
        $Name = $env:COMPUTERNAME
    )

    Process
    {
        Write-Verbose "Running query.exe against $Name."
        $Users = query user /server:$Name 2>&1

        if ($Users -like "*No User exists*")
        {
            # Handle no user's found returned from query.
            # Returned: 'No User exists for *'
            Write-Error "There were no users found on $Name : $Users"
            Write-Verbose "There were no users found on $Name."
        }
        elseif ($Users -like "*Error*")
        {
            # Handle errored returned by query.
            # Returned: 'Error ...<message>...'
            Write-Error "There was an error running query against $Name : $Users"
            Write-Verbose "There was an error running query against $Name."
        }
        elseif ($Users -eq $null -and $ErrorActionPreference -eq 'SilentlyContinue')
        {
            # Handdle null output called by -ErrorAction.
            Write-Verbose "Error action has supressed output from query.exe. Results were null."
        }
        else
        {
            Write-Verbose "Users found on $Name. Converting output from text."

            # Conversion logic. Handles the fact that the sessionname column may be populated or not.
            $Users = $Users | ForEach-Object {
                (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1  none  $2' -replace "\s{2,}", "," -replace "none", $null))
            } | ConvertFrom-Csv

            Write-Verbose "Generating output for $($Users.Count) users connected to $Name."

            # Output objects.
            foreach ($User in $Users)
            {
                Write-Verbose $User
                if ($VerbosePreference -eq 'Continue')
                {
                    # Add '| Out-Host' if -Verbose is tripped.
                    [PSCustomObject]@{
                        ComputerName = $Name
                        Username = $User.USERNAME
                        SessionState = $User.STATE.Replace("Disc", "Disconnected")
                        SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
                    } | Out-Host
                }
                else
                {
                    # Standard output.
                    [PSCustomObject]@{
                        ComputerName = $Name
                        Username = $User.USERNAME
                        SessionState = $User.STATE.Replace("Disc", "Disconnected")
                        SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
                    }
                }
            }
        }
    }
}

そして今、あなたは以下のようなことをすることができます: Get-ADComputer -Filter {Name -like "SERVER*"} | Convert-QueryToObjects | ? {$_.SessionState -eq 'Active'}


唯一の問題はです。の quser ローカル言語で出力を返します。これは、異なる言語を使用する可能性があるリモートマシンで実行したい場合に問題になります。
Reddy

さまざまな言語を処理するように関数を変更することはできますが、残念ながら、必要な情報を取得するための実際の代替方法はありません。実行可能な純粋なPowerShellの唯一の方法は、リモートマシンでexplorer.exeプロセスの実行を確認することですが、アクティブセッションと切断セッションを区別することはできません。そうは言っても、今こそあなたのサーバーのインストール言語を標準化し、ユーザーに彼らの個人的なUI言語のニーズに合わせてSet-WinUILanguageOverrideを利用させることを検討する時であるかもしれません。
omniomi

1

これが私のやり方です。しかし、rdpセッションでは動作しません。

$out = query session | where {$_ -match 'console'}
$array = $out -split('\s+')
$consoleuser = $array[1]

または

$consoleuser = query session | select-string console | foreach { -split $_ } | 
  select -index 1

-1

これは次のようにして行うことができます。

get-wmiobject - クラスユーザー名を選択

よろしく


RDP :(からリモートマシンで実行すると、空の結果になります。
Reddy

1
WMIクエリは、ユーザーがlocalyでサインインして取得します。RDPセッションを取得するには、 "qwinsta"を試してください。 gallery.technet.microsoft.com/scriptcenter/…
s0mm3r
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.