关于活动目录:结合powershell输出

Combine powershell output

我正在尝试将两个函数的输出与默认 Get-ADUser-cmdlet 的输出相结合。我对创建帐户的时间感兴趣,它是否被锁定以及它的名称是什么。我还想知道用户上次登录的时间(使用多个 DC)以及该帐户是否被用作共享邮箱。

我写了两个自定义函数Get-ADUserLastLogonisSharedMailbox,两个函数都使用Write-Output函数来输出它们的输出。如果是 Get-ADUserLastLogon,这将是 Lastlogon:时间,如果是 isSharedMailbox,这将是共享的:yes/no。我还在 foreach 循环中使用标准 Get-ADUser 调用

现在,Get-ADUser 的默认输出是:

SAMAccountName LockedOut Created
-------------- --------- -------
ACC False 23-10-2015 8:20:20

自定义函数的输出如下:

Lastlogon : 1-1-1601 1:00:00

Shared: yes

我想要将 LastLogon 和 Shared 'headers' 组合到 Get-ADUser 中。所以输出会变成:

SAMAccountName LockedOut Created LastLogon Shared

当前代码的代码,其中帐户从 Excel 工作表中导入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
foreach($username in $usernameWithTld){
    if ($username -eq $NULL){
        break
    }

    $usernameWithoutTld = $username.split('\')

    Get-ADUser $usernameWithoutTld[1] -Properties LockedOut, SamAccountName,
    Created -ErrorAction Stop | Select-Object SAMAccountName, LockedOut,
    Created

    Get-ADUserLastLogon -UserName $usernameWithoutTld[1]

   # Shared mailbox?

   isSharedMailbox -mailboxname $usernameWithoutTld[1]
}

功能代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function isSharedMailbox([string]$mailboxname){
    $isObject = Get-ADUser  -Filter {name -eq $mailboxname} -SearchBase"..." | Select-Object DistinguishedName,Name

    if ($isObject -match"DistinguishedName"){
        $output ="Shared: no"
        Write-Output $output
    } else {
        $output ="Shared: No"
        Write-Output $output
    }

}


function Get-ADUserLastLogon([string]$userName){

  $dcs = Get-ADDomainController -Filter {Name -like"*"}
  $time = 0
  foreach($dc in $dcs)
  {
    $hostname = $dc.HostName
    $user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
    if($user.LastLogon -gt $time)
    {
      $time = $user.LastLogon
    }
  }
  $dt = [DateTime]::FromFileTime($time)
  Write-Output"LastLogon : $dt"

}

我确信可以进行很多改进,我仍在学习如何编写(正确的)PowerShell。希望有人能回答我的问题。


您可以在 Select-Object 中使用计算属性。查看 MSDN 页面的示例 4。

在你的情况下,这将是:

1
2
Get-ADUser $usernameWithoutTld[1] -Properties LockedOut, SamAccountName, Created -ErrorAction Stop | `
Select-Object SAMAccountName, LockedOut, Created, @{Name='LastLogon';Expression={Get-ADUserLastLogon -UserName $usernameWithoutTld[1]}}, @{Name='IsSharedMailbox';Expression={isSharedMailbox -mailboxname $usernameWithoutTld[1]}}

或者更好的是,您可以使用 Get-ADUser 放入管道中的对象依次调用该特定对象的函数,并且在您的查询返回多个结果时很有用:

1
2
Get-ADUser $usernameWithoutTld[1] -Properties LockedOut, SamAccountName, Created -ErrorAction Stop | `
Select-Object SAMAccountName, LockedOut, Created, @{Name='LastLogon';Expression={Get-ADUserLastLogon -UserName $_.sAMAccountName}}, @{Name='IsSharedMailbox';Expression={isSharedMailbox -mailboxname $_.sAMAccountName}}


一种方法是让您的函数返回您感兴趣的值,将它们存储在变量中,然后将所有内容组合成一个包含您感兴趣的属性的 PSObject。

存储为对象的好处很多。例如,您可以在管道中使用 Select-ObjectSort-Object 等,或使用 Export-CSV 和其他需要 InputObject

的 Cmdlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
foreach($username in $usernameWithTld){
    if ($username -eq $NULL){
        break
    }

    $usernameWithoutTld = $username.split('\')

    $adDetails = Get-ADUser $usernameWithoutTld[1] -Properties LockedOut, SamAccountName,
    Created -ErrorAction Stop | Select-Object SAMAccountName, LockedOut,
    Created

    $lastlogin = Get-ADUserLastLogon -UserName $usernameWithoutTld[1]

   # Shared mailbox?

   $isshared = isSharedMailbox -mailboxname $usernameWithoutTld[1]

   # putting together the PSobject
   [array]$myResults += New-Object psobject -Property @{
        SAMAccountName = $adDetails.SAMAccountName
        LockedOut      = $adDetails.LockedOut
        Created        = $adDetails.Created
        LastLogon      = $lastlogin
        Shared         = $shared # true/false or yes/no, depending on function
        #Shared         = if($shared){"yes"}else{"no"} # yes/no, based on true/false from function

   }
}

功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function isSharedMailbox([string]$mailboxname){
    $isObject = Get-ADUser  -Filter {name -eq $mailboxname} -SearchBase"..." | Select-Object DistinguishedName,Name

    return ($isObject -match"DistinguishedName") # returns true/false

    <# if you prefer to keep yes/no
    if ($isObject -match"DistinguishedName"){
        return"Yes"  # no in original code
    } else {
        return"No"
    }
    #>

}

function Get-ADUserLastLogon([string]$userName){

  $dcs = Get-ADDomainController -Filter {Name -like"*"}
  $time = 0
  foreach($dc in $dcs)
  {
    $hostname = $dc.HostName
    $user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
    if($user.LastLogon -gt $time)
    {
      $time = $user.LastLogon
    }
  }
  $dt = [DateTime]::FromFileTime($time)

  return $dt
  #Write-Output"LastLogon : $dt"

}


您可以将函数的结果存储在全局变量中,最后将它们连接起来是一种方法。

否则,您可以使用返回函数的输出并稍后使用该值或类似: $value= functionname 然后 $value 将保存函数的返回值,稍后您可以组合结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function isSharedMailbox([string]$mailboxname){
    $isObject = Get-ADUser  -Filter {name -eq $mailboxname} -SearchBase"..." | Select-Object DistinguishedName,Name

    if ($isObject -match"DistinguishedName"){
        $output ="Shared: no"
        $Global:result1= $output
    } else {
        $output ="Shared: No"
        $Global:result1= $output
    }

}


function Get-ADUserLastLogon([string]$userName){

  $dcs = Get-ADDomainController -Filter {Name -like"*"}
  $time = 0
  foreach($dc in $dcs)
  {
    $hostname = $dc.HostName
    $user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
    if($user.LastLogon -gt $time)
    {
      $time = $user.LastLogon
    }
  }
  $dt = [DateTime]::FromFileTime($time)
  $Global:result2="LastLogon : $dt"

}
## Calling the function . Change the placeholders accordingly
Get-ADUserLastLogon -UserName $usernameWithoutTld[1]
isSharedMailbox -mailboxname $usernameWithoutTld[1]

$FinalResult ="result1" +"result2"
$FinalResult

希望它能帮助你更好地理解。