【问题标题】:Combine powershell output结合powershell输出
【发布时间】:2017-06-14 10:15:08
【问题描述】:

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

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

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

SAMAccountName LockedOut 创建
-------------- --------- --------
ACC 错误 23-10-2015 8:20:20

自定义函数的输出如下:

最后登录:1-1-1601 1:00:00

共享:是的

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

SAMAccountName LockedOut Created LastLogon Shared

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

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]
}

功能代码:

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。希望有人能回答我的问题。

【问题讨论】:

  • isSharedMailbox 将始终返回 No,可能需要解决此问题 ;)

标签: powershell active-directory


【解决方案1】:

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

在你的情况下,这将是:

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 放入管道中的对象依次调用该特定对象的函数,并且在您的查询返回多个结果时很有用:

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}}

【讨论】:

  • 这正是我要找的。非常感谢您的解释和解决方案! :)
  • @Brainscrewer,上面的脚本仅适用于 OnPremise 还是 Hybrid-Office365 ?
【解决方案2】:

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

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

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

   }
}

功能:

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"

}

【讨论】:

  • 以上脚本仅适用于 OnPremise 还是 Hybrid-Office365 ?
【解决方案3】:

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

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

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

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

【讨论】:

  • 我不想使用全局变量,因为计算属性是一种更优雅的方法。
  • @JamesC.:是的。我只是不想更改该上下文中的任何代码。 :)
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多