web-dev-qa-db-ja.com

PowerShellで「クエリユーザー」を解析する簡単な方法

現在、PowerShellに次のクエリがあります。

_query user /server:$server
_

出力を返すもの:

_USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME  
svc_chthost                               2  Disc         1:05  8/16/2016 12:01 PM  
myusername                rdp-tcp         3  Active          .  8/29/2016 11:29 AM
_

現在、ログオンしているユーザーの数を表す値として@(query user /server:$server).Count - 1を使用しています(かなりわかりません)。ただし、スクリプトの他の部分で使用するUSERNAMEID、_LOGON TIME_などの情報を取得したいと思います。

私の質問は、上記の情報を解析する簡単な方法、またはおそらく私の問題に対するより良い解決策を囲んでいます:ログオンしたユーザーに関連する情報のカウントと収集。

私はもっ​​とうまくいくように見える他の解決策を見つけましたが、このタスクを達成するためのより簡単な方法があるはずだと確信しています:

_$ComputerName | Foreach-object { 
$Computer = $_ 
try 
    {
        $processinfo = @(Get-WmiObject -class win32_process -ComputerName $Computer -EA "Stop") 
            if ($processinfo) 
            {     
                $processinfo | Foreach-Object {$_.GetOwner().User} |  
                Where-Object {$_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM"} | 
                Sort-Object -Unique | 
                ForEach-Object { New-Object psobject -Property @{Computer=$Computer;LoggedOn=$_} } |  
                Select-Object Computer,LoggedOn 
            }#If 
    } 
catch 
    { 

    }
_
8
Tyler Dickson

コメントでの素晴らしい参照、そしてより簡単な解決策があるはずなので、この質問に対するより多くの回答を受け入れることができます!

    foreach ($s in $servers) #For Each Server
{
    foreach($ServerLine in @(query user /server:$s) -split "\n") #Each Server Line
    {
        #USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME

        $Parsed_Server = $ServerLine -split '\s+'

        $Parsed_Server[1] #USERNAME
        $Parsed_Server[2] #SESSIONNAME
        $Parsed_Server[3] #ID
        $Parsed_Server[4] #STATE
        $Parsed_Server[5] #IDLE TIME
        $Parsed_Server[6] #LOGON TIME
    }
}

このソリューションは、今のところ問題を解決しています。

より多くの機能を備えたより詳細なソリューションについては、元の質問のコメントを確認してください:)

3
Tyler Dickson
Function Get-QueryUser(){
Param([switch]$Json) # ALLOWS YOU TO RETURN A JSON OBJECT
    $HT = @()
    $Lines = @(query user).foreach({$(($_) -replace('\s{2,}',','))}) # REPLACES ALL OCCURENCES OF 2 OR MORE SPACES IN A ROW WITH A SINGLE COMMA
    $header=$($Lines[0].split(',').trim())  # EXTRACTS THE FIRST ROW FOR ITS HEADER LINE 
    for($i=1;$i -lt $($Lines.Count);$i++){ # NOTE $i=1 TO SKIP THE HEADER LINE
        $Res = "" | Select-Object $header # CREATES AN EMPTY PSCUSTOMOBJECT WITH PRE DEFINED FIELDS
        $Line = $($Lines[$i].split(',')).foreach({ $_.trim().trim('>') }) # SPLITS AND THEN TRIMS ANOMALIES 
        if($Line.count -eq 5) { $Line = @($Line[0],"$($null)",$Line[1],$Line[2],$Line[3],$Line[4] ) } # ACCOUNTS FOR DISCONNECTED SCENARIO
            for($x=0;$x -lt $($Line.count);$x++){
                $Res.$($header[$x]) = $Line[$x] # DYNAMICALLY ADDS DATA TO $Res
            }
        $HT += $Res # APPENDS THE LINE OF DATA AS PSCUSTOMOBJECT TO AN ARRAY
        Remove-Variable Res # DESTROYS THE LINE OF DATA BY REMOVING THE VARIABLE
    }
        if($Json) {
        $JsonObj = [pscustomobject]@{ $($env:COMPUTERNAME)=$HT } | convertto-json  # CREATES ROOT ELEMENT OF COMPUTERNAME AND ADDS THE COMPLETED ARRAY
            Return $JsonObj
        } else {
            Return $HT
        }
}


Get-QueryUser
  or
Get-QueryUser -Json
1
machinevault

古い質問ですが、それは実行可能な解決策のようです:

(query user) -split "\n" -replace '\s\s+', ';' | convertfrom-csv -Delimiter ';'

これは、上記の回答と同様に、出力を行に分割しますが、複数の空白文字(\ s\s +)をセミコロンで置き換え、セミコロンを区切り文字として使用してcsvからの出力を変換します。

複数の空白の理由は、列ヘッダーに空白(アイドル時間、ログオン時間)が含まれるためです。空白が1つしかない場合、空白が複数の列として解釈されます。コマンドの出力から、いずれにしてもアイテム間のスペースは常に2つ以上保持されているように見え、ログオン時間の列にもフィールドにスペースがあります。

1
omrsafetyo