将列表input传递给Get-ADComputer

所以我写了一个脚本,从AD获取关于用户及其相关计算机的一些信息。 我已经在线阅读了关于Get-ADComputer cmdlet以及一些可能的错误的人们面临的一些问题。 起初我以为那是我碰到的,但现在我不太确定。

我的问题是,我的代码工作正常,但如果我添加一个不相关的代码片段从variables获取一些信息,它打破了别的东西。 看一看。

整个代码: http : //paste.ofcode.org/Hgbiukp2XYqKnv2sdUGBKb

有问题的代码位:

## Prompt host for input $username = Read-Host -Prompt "Enter the Username" ## Get list of computers $ComputerList = Get-ADComputer -Filter {ManagedBy -eq $username} -Properties ManagedBy | Select-Object -ExpandProperty Name ## Compute and format results Foreach ($Computer in $ComputerList) { $OnlineStatus = Test-Connection -ComputerName $Computer -BufferSize 16 -Count 1 -Quiet If ($OnlineStatus -like "True") {$OnlineStatus = "$True"} else {$OnlineStatus = "$False"} Get-ADComputer -Identity $Computer -Properties ManagedBy,DNSHostName,LastLogonTimestamp | Select-Object DNSHostName,@{Name="Active";Expression={$OnlineStatus}},@{Name="LastLogonTimestamp";Expression={[datetime]::FromFileTime($_.LastLogonTimestamp)}} } 

所以这部分工作完美。 现在,如果您添加一个获取有关用户名的信息的代码段,您可以看到它停止显示关于AD计算机的输出。

 ## Prompt host for input $username = Read-Host -Prompt "Enter the Username" ## Get Username info Get-ADUser -Identity $username –Properties “DisplayName”, “msDS-UserPasswordExpiryTimeComputed”, "LockedOut" | Select-Object -Property @{Name="Name";Expression={$_.DisplayName}},@{Name=“PWD Expiration Timestamp”;Expression={[datetime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}},LockedOut ## Get list of computers $ComputerList = Get-ADComputer -Filter {ManagedBy -eq $username} -Properties ManagedBy | Select-Object -ExpandProperty Name ## Compute and format results Foreach ($Computer in $ComputerList) { $OnlineStatus = Test-Connection -ComputerName $Computer -BufferSize 16 -Count 1 -Quiet If ($OnlineStatus -like "True") {$OnlineStatus = "$True"} else {$OnlineStatus = "$False"} Get-ADComputer -Identity $Computer -Properties ManagedBy,DNSHostName,LastLogonTimestamp | Select-Object DNSHostName,@{Name="Active";Expression={$OnlineStatus}},@{Name="LastLogonTimestamp";Expression={[datetime]::FromFileTime($_.LastLogonTimestamp)}} } 

有人能告诉我这是为什么吗? 以及如何解决它?

通常情况下,我可以通过玩弄它,但这个真的让我难住。 我认为问题必须与$ComputerListvariables的格式,但列表中的每个项目是一个string,这是什么Get-ADComputer需要。 所以我只是不知道。

谢谢大家。

我相信你的问题是围绕这样一个事实,即你正在向输出pipe道写入多种不同types的对象(隐式地通过不把它们分配给一个variables),并依靠默认的Powershell格式规则将它们正确地显示到控制台(它可以“T)。

它显示第一种types的对象,然后尝试使用与第一种相同的格式化程序显示第二种types的对象,然后只写空白行。 如果将Get-ADUser调用移动到Get-ADComputer调用的循环下面,则会出现相反的问题。

假设这个脚本的输出只是意图在控制台上显示,而不是由其他脚本进一步处理或者与其他cmdlet链接,您可能希望使用Write-Host对输出的每个部分进行显式格式化。 通常情况下,这是一个坏主意 。 像这样的东西。

 $user = Get-ADUser -Identity $username –Properties “DisplayName”, “msDS-UserPasswordExpiryTimeComputed”, "LockedOut" Write-Host "User: $($user.DisplayName)`tPWD Expiration: $([datetime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”))`tLockedOut: $($user.LockedOut)" 

我还想就脚本的一般结构提供一些额外的build议。

首先,我会让你的$usernamevariables成为一个必须的参数,而不是明确地调用Read-Host 。 如果没有在命令行中指定,PowerShell会自动提示。

当您检查usere的存在时,您将$usernamevariables的对象types从string更改为ADUser对象。 我猜这不是你的意图,只是幸运的是后来的引用它使用对象而不是string。 此后,您还需要进行第二次Get-ADUser调用,以获取您关心的属性,这些属性会额外往返于域控制器。 我只是把这两个结合起来,并把你的## Get Username info部分到try / catch块中。 如果用户不存在,它仍会抛出相同的exception。 我也将输出分配给一个新的variables,如$user

或者,您也可以跳过所有的exception处理,并将Get-ADUser调用更改为使用-Filter {SamAccountName -eq $username}参数,然后像Get-ADComputer一样testing$ null。

您最终还会将您的电话复制到Get-ADComputer。 首先你用filter调用,然后你重新调用每个结果。 只需将DNSHostName,LastLogonTimestamp属性添加到初始调用中,然后直接在结果对象上迭代而不需要重新调用Get- DNSHostName,LastLogonTimestamp就会更有效。

以下是由此产生的脚本的样子:

 param( [Parameter(Mandatory=$true,Position=0)] [string]$username ) # Import AD Module Import-Module ActiveDirectory Write-Host "Active Domain: $((Get-ADDomain).DNSRoot)" # Get user details $user = Get-ADUser -Filter {SamAccountName -eq $username} -Properties DisplayName,msDS-UserPasswordExpiryTimeComputed,LockedOut If ($user -eq $null) { Write-Error "Error: Username not found. Exiting" Exit } Write-Host "Name: $($user.DisplayName)" Write-Host "PWD Expiration Timestamp: $([datetime]::FromFileTime($_.'msDS-UserPasswordExpiryTimeComputed'))" Write-Host "LockedOut: $($user.LockedOut)" # Get managed computers $ComputerList = Get-ADComputer -Filter {ManagedBy -eq $username} -Properties ManagedBy,DNSHostName,LastLogonTimestamp # Error-Handling: If no computers found If ($ComputerList -eq $null) { Write-Error "No computers found" Exit } # Compute and format results ForEach ($computer in $ComputerList) { $OnlineStatus = Test-Connection -ComputerName $computer.Name -BufferSize 16 -Count 1 -Quiet # since this is now the only type of object we will be putting on the pipeline, # it's ok to just do that now $computer | Select-Object DNSHostName,@{L="Active";E={$OnlineStatus}},@{L="LastLogonTimestamp";E={[datetime]::FromFileTime($_.LastLogonTimestamp)}} | Write-Output }