powershell:从变量内容

时间:2016-09-30 02:06:01

标签: powershell csv

我正在编写一个脚本,该脚本接受来自sysinternals命令的输出:psloggedon.exe并输出计算机名称以及用户登录的内容。

我目前有脚本产生以下可能性,具体取决于查询时每台计算机给出的输出。

  

DOMAIN \计算机name01
  DOMAIN \用户名

     

DOMAIN \计算机name02
  域\用户名
  DOMAIN \用户名

     

DOMAIN \计算机姓名03,2
  连接错误

     

DOMAIN \计算机姓名04,2
  没有用户登录

每个数据块将始终具有计算机名称,后跟登录的用户列表,错误或表示没有人登录的消息。

我想将数据分配给自定义对象,以便我可以将其输出到CSV。据我所知,这是生成正确CSV的最佳方式。

我对自定义对象感到困惑的是,我该如何处理传入数据数量变化的情况?例如,我可能有一台有4人登录的计算机。我也不明白如何创建列标题。我发现大多数示例中的数据都被提供给自定义对象已经拥有了自己的列标题或属性。

我希望输出数据,使其看起来像下面的

  

DOMAIN \ computer-name,DOMAIN \ user-name,DOMAIN \ user-name
  DOMAIN \ computer-name,错误消息
  DOMAIN \ computer-name,没有人登录

计算机名称上的列标题为“计算机名称”,登录用户/错误消息的标题/没有人登录将为“状态”。

微软似乎记录了这一点:https://technet.microsoft.com/en-us/library/ff730946.aspx

在这个例子中,我不明白“$ objBatter.Name”的来源。脚本如何知道输入中的属性或列标题?输入的数据是否已经定义了?

很抱歉这么令人困惑,我很难将我的大脑包裹起来,所以解释它很难。

这是我尝试过的。但基本上自定义对象只输出属性/列标题(抱歉,我不确定这是什么)。其余的都是空白的。

$Computers = @(
,"computer-name01"
)

Foreach ( $Computer in $Computers)
{
    $loggedon = $null
    If ( Test-Connection -ComputerName $Computer -Quiet -Count 1 )
    {
        $loggedon = (PsLoggedon.exe -x -l \\$Computer | Where-Object { ($_ -like "*DOMAIN\*" -or $_ -like "*No one*" -or $_ -like "*$Computer\*" -or $_ -like "*Error opening*")}).trim()

        if ( $loggedon -like "*Error Opening*" )
        {
            Write-Output "Error occurred while attempting to connect. This computer is online."
            Continue
        } else {

            $loggedon = ,"$Computer" + $loggedon

            $colComputerAndUser = @()

            foreach ($item in $loggedon)
            {
                $ObjComputerAndUser = New-Object System.Object
                $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $item.Computer
                $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $item.User
                $colComputerAndUser += $ObjComputerAndUser
            }

            $colComputerAndUser
        }
    }
 }

更新01

我试图使用您提供的代码。它按预期工作,但如果计算机返回的不仅仅是一个登录的人,我会得到一个奇怪的行为。 在自定义对象内,计算机将多次显示。

$Computers = @(
,"computer01"
,"computer02"
)

$colComputerAndUser = @()

Foreach ( $Computer in $Computers)
{
    $loggedon = $null
    If ( Test-Connection -ComputerName $Computer -Quiet -Count 1 )
    {
        $loggedon = (PsLoggedon.exe -x -l \\$Computer | Where-Object { ($_ -like "*DOMAIN\*" -or $_ -like "*No one*" -or $_ -like "*$Computer\*" -or $_ -like "*Error opening*")}).trim()
        $loggedon = [string]$loggedon
        $ObjComputerAndUser = New-Object PSObject
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $Computer
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $loggedon
        $colComputerAndUser += $ObjComputerAndUser     
    }

    $colComputerAndUser
}
  

电脑用户
  -------- ----
  computer01 DOMAIN \ user01 DOMAIN \ user02
  computer01 DOMAIN \ user01 DOMAIN \ user02
  computer02 DOMAIN \ user03

更新02

从PsLoggedon.exe取出样本01 - 未经编辑

PsLoggedon v1.35 - See who's logged on  
Copyright (C) 2000-2016 Mark Russinovich  
Sysinternals - www.sysinternals.com  

Users logged on locally:  
        DOMAIN\user.name01  
        DOMAIN\user.name02

从PsLoggedon.exe中取出样本02 - 未经编辑

PsLoggedon v1.35 - See who's logged on  
Copyright (C) 2000-2016 Mark Russinovich  
Sysinternals - www.sysinternals.com  

Users logged on locally:  
        LOCALMACHINE\local.user01
        LOCALMACHINE\local.user04
        DOMAIN\user.name15  
        DOMAIN\user.name17

更新03 这段代码实际上正在运行,但我把它放在代码的错误部分。

$Computers = @(
,"computer01"
,"computer02"
,"computer03"
,"computer04"
,"computer05"
)

$colComputerAndUser = @()

Foreach ( $Computer in $Computers)
{
    $loggedon = $null
    If ( Test-Connection -ComputerName $Computer -Quiet -Count 1 )
    {
        $loggedon = (PsLoggedon.exe -x -l \\$Computer | Where-Object { ($_ -like "*DOMAIN\*" -or $_ -like "*No one*" -or $_ -like "*$Computer\*" -or $_ -like "*Error opening*")}).trim()
        $loggedon = [string]$loggedon
        $ObjComputerAndUser = New-Object PSObject
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $Computer
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $loggedon
        $colComputerAndUser += $ObjComputerAndUser     
    }
}
$colComputerAndUser

此代码不同的地方是放置最终$ colComputerNameUser的位置。最初我把它包含在foreach循环中,这导致输出重复。它现在出现在循环之后,输出正常工作。

1 个答案:

答案 0 :(得分:1)

创建一个具有两个属性的对象:ComputerName,Users。 将ComputerName之后的所有值连接到一个字符串中,并将该字符串分配给Users属性。

$Computers = @(,"computername")

Foreach ($Computer in $Computers)
{
$loggedon = $null
if (Test-Connection -ComputerName $Computer -Quiet -Count 1){
    $loggedon = (.\PsLoggedon.exe -x -l \\$Computer)

    if ($loggedon -like "*Error Opening*"){
        Write-Output "Error occurred while attempting to connect. This computer is online."
        Continue
    } else {
        $loggedon = ,"$Computer" + $loggedon

        $colComputerAndUser = @()

        $UserString = ""
        for($Cnt = 9;$Cnt -lt $loggedon.Count;$Cnt++)
        {
            $UserString += ($loggedon[$Cnt]).Trim() + "`n"
        }
        $ObjComputerAndUser = New-Object System.Object
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $Computer
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $UserString
        $colComputerAndUser += $ObjComputerAndUser
     }
   }
 }
$colComputerAndUser | format-table -wrap

不是我最优雅的作品,但它有效。我不喜欢将数组计数的开头硬编码为9.我试图拆分冒号,但它只是在PsLoggedon的输出中的每一个上分开。我可能会稍后尝试改进它。我还尝试了一个全局正则表达式匹配[正则表达式]'(?[^ \])\(?。*)'但那也没有成功。我得到了结果,但无法列举结果。