Powershell - 输出,ADuser SamAccountName、UserPrincipalName 和 ADcomputer Name 相同的表

问题描述 投票:0回答:1

Powershell 的总 n00b。我决定开始学习 Powershell,因为我在工作中执行了一些标准流程,我希望自动化/简化这些流程。我熟悉其他脚本/编程语言,例如 Python 和 Bash,但不是很熟练。我试图简化的过程是在同一个表中获取 AD 中的基本用户信息(ADuser SamAccountName、UserPrincipalName 和 ADcomputer Name)。我试图通过与用户登录名匹配的计算机描述来获取计算机名称,并将所有信息输出到一个整洁的表格中。

在工作中,我们使用 TeamViewer 远程访问我们的用户系统。我更喜欢使用用户计算机名进行远程访问,而不是他们的 ID,因为我厌倦了解释 TeamViewer 不是 MS Teams 以及在哪里可以找到 ID。无论如何,要查找电脑名称,我需要首先在 AD 中获取用户登录名,然后通过计算机描述搜索计算机。我们有大约 25 个组织单位,其中都有大约 100 名用户和计算机。因此手动遍历每个 OU 来查找它是不可能的。当我每天需要与用户通电话并倾听他们遇到的问题时执行 60 次时,这变得非常乏味。

我们的新用户的登录名是“firstlastname”。年长员工的登录名均以相同的开头,但以姓名首字母“公司名首字母”结尾。我正在尝试编写一个脚本,当运行时提示用户输入真实姓名,无论登录名如何,然后让它吐出所有相关信息。如果它输出具有相似名称的多个用户信息(例如“Sarah”或“John”),那就没问题。只要它能把信息组织得井井有条,我和我的团队就会很高兴。我已经尝试了大约一个月,但未能掌握某些 cmdlet 实际工作原理和最佳实践的一些概念。

任何意见都值得赞赏,但请放轻松,因为我还不太了解 Powershell 的高级概念,而且我知道我编写了垃圾代码。我正在努力变得更好。

我尝试了很多不同的事情,我需要写一本 10 章的书。然而,我最接近得到它的是创建一个新对象。当脚本运行时,它会获取所有正确的信息,但将每条信息放在每个对象成员下,但不分开。所有这些都被捣碎成一根长绳。不知道如何准确解释。但这是迄今为止的整个脚本。我假设我需要在某个地方使用 ForEach 但不确定如何正确执行此操作。我认为我不需要保留对象创建部分,以便将其删除,但我将其放在这里供所有人查看它的外观。也许 if 语句不是正确的方法,我不确定。

$Name = Read-Host -Prompt " " 

$UserAccount = Get-ADUser -Filter "Name -like '*$Name*'" 

if($UserAccount.SamAccountName -like "companyname-initials*") {
    
    $UserCpu = Get-ADComputer -Filter "Description -like 'companyname-initials*'"
    

} else { 

    $UserCpu = Get-ADComputer -Filter "Description -like '*$Name*'" 

}

$Output = [pscustomobject]@{
    Email = $UserAccount.UserPrincipalName
    Login = $UserAccount.SamAccountName
    PCName = $UserCpu.Name
    }
$Output | Select-Object Email,Login,PCName

如果有什么需要更好的解释,请告诉我。

谢谢!

powershell active-directory
1个回答
0
投票

当脚本运行时,它会获取所有正确的信息,但将每条信息放在每个对象成员下,但不分开。全部捣碎成一根长绳。

成员访问枚举

从字里行间看出,我认为您无意中使用了名为“成员访问枚举”的功能。 # set up some test data $users = @( [pscustomobject] @{ "firstname" = "vic"; "lastname" = "reeves" }, [pscustomobject] @{ "firstname" = "bob"; "lastname" = "mortimer" } ); # build the result object $output = [pscustomobject] @{ "firstname" = $users.firstname "lastname" = $users.lastname "pcname" = "..." } # display the result $output | format-table

这显示以下输出:

firstname lastname pcname --------- -------- ------ {vic, bob} {reeves, mortimer} {..., ...}

因为 
$users

是一个包含多个值的

array
,所以 $users.firstname 正在做的是使用成员访问枚举来构建
firstname
数组中对象的
$users
属性的数组 - 结果等价于 @("vic, "bob"),与
$users.lastname
相同,给出
@("reeves", "mortimer")
当这些值呈现到屏幕上时,它们将按上述方式序列化。
解决方案

要修复此问题,您需要迭代

$users

数组并一次转换一个用户:

$output = @() foreach( $user in $users ) { [pscustomobject] @{ "firstname" = $user.firstname; "lastname" = $user.lastname "pcname" = "..." } } # display the result $output | format-table

现在给出以下输出:

firstname lastname pcname
--------- -------- ------
vic       reeves   ...
bob       mortimer ...

在您的情况下,根本原因是

$UserAccount = Get-ADUser -Filter "Name -like '*$Name*'"
 返回 
多个

帐户,因此您需要迭代它们:

$Name = Read-Host -Prompt " " 

# might contain multiple accounts
$UserAccounts = Get-ADUser -Filter "Name -like '*$Name*'" 

# loop over each account adding it to the $output array
$output = @()
foreach( $UserAccount in $UserAccounts )
{
    if($UserAccount.SamAccountName -like "companyname-initials*") {
        $UserCpu = Get-ADComputer -Filter "Description -like 'companyname-initials*'"
    } else { 
        $UserCpu = Get-ADComputer -Filter "Description -like '*$Name*'" 
    }

    $Output += [pscustomobject]@{
        Email = $UserAccount.UserPrincipalName
        Login = $UserAccount.SamAccountName
        PCName = $UserCpu.Name
    }
}

# show the results
$Output | Format-Table

您现在应该每行获得一个帐户...

在上面为简单起见,我使用了一种称为 
加法赋值运算符

的东西 -

+=

行中的 $Output += [pscustomobject]@{ ... } - 简单来说,这会将一个项目附加到

$Output
数组,
但是 
它如果您正在处理非常大的数据集,则可能会出现性能问题 - 对于这个答案来说,这很好,并且对于小型数据集来说它也可以正常工作,但是如果您看到您的代码在处理大量结果时开始运行缓慢,那么这是第一个看的地方...
管道
为了避免“加法分配”运算符的性能问题,您可以使用管道重写示例以收集每个用户帐户的所有结果:

# loop over each account adding it to the $output array $output = $users | foreach-object { if($_.SamAccountName -like "companyname-initials*") { $UserCpu = Get-ADComputer -Filter "Description -like 'companyname-initials*'" } else { $UserCpu = Get-ADComputer -Filter "Description -like '*$Name*'" } # this implicitly returns the values to the pipeline to be # collected into the $output variable as an array [pscustomobject]@{ Email = $_.UserPrincipalName Login = $_.SamAccountName PCName = $UserCpu.Name } }

这应该会产生与之前的解决方法相同的结果,但不会遇到相同的性能问题...

© www.soinside.com 2019 - 2024. All rights reserved.