远程 Powershell:术语 'Where-Object' 在 "Invoke-Command" 中无法识别

Remote Powershell: The term 'Where-Object' is not recognized in "Invoke-Command"

当我 运行 在我的 Exchange 服务器上本地执行以下命令时,

$username = 'username'; $password = ConvertTo-SecureString 'password' -asplaintext -force; $UserCredential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,$password; $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'http://exchange.myfirm.local/PowerShell' -Authentication Kerberos -Credential $UserCredential; Invoke-Command -Session $Session {Get-Mailbox -RecipientTypeDetails 'SharedMailbox' | Get-MailboxPermission | Where-Object User -like 'anotherusername' | fl identity}

我收到此错误消息:

The term 'Where-Object' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    + CategoryInfo          : ObjectNotFound: (Where-Object:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : exchange.myfirm.local

如何将此 cmdlet 添加到此 "session" 或解决此问题?

背景: 我正在尝试使用 winrm 使用 ruby 脚本远程自动化一些东西,但还没有找到任何其他连接到 Exchange Powershell "Layer" 的替代方法。

在 "real" Exchange Management Shell 上,此命令运行良好(因此我认为整个 powershell 安装没有损坏(模块 Microsoft.PowerShell.Utility))。我认为它更像是我通过 "New-PSSession" 和 "Invoke-Command" 连接到这个 shell 的方式。

如果有帮助,这里是 ruby 代码(但我认为这与我远程连接电源的方式无关 shell - 但如果有更好的方法, 请告诉我):

require 'winrm'

$exch_user = 'username'
$exch_password = 'password'

endpoint = 'http://ipaddress:5985/wsman' # this is the connection URI to the Exchange 
connectionuri = 'http://exchange.myfirm.local/PowerShell' # keep in mind that the PowerShell URI MAY have to be a FQDN
winrm = WinRM::WinRMWebService.new(endpoint, :plaintext, :user => $exch_user, :pass => $exch_password, :basic_auth_only => true)
executor = winrm.create_executor

exch_cmd = "Get-Mailbox anotherusername | Select-Object -expand EMailAddresses alias"

command = "powershell -NonInteractive -WindowStyle Hidden -command \" $username = '#{$exch_user}'; $password = ConvertTo-SecureString '#{$exch_password}' -asplaintext -force; $UserCredential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,$password; $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri '#{connectionuri}' -Authentication Kerberos -Credential $UserCredential; Invoke-Command -Session $Session {#{exch_cmd}}\""

#$i = 0
$a ||= Array.new
executor.run_cmd(command) do |stdout, stderr|
    stdout.each_line do |l|
        $a << l[21..-1] if l.match(/^AddressString/)
    end
  #STDOUT.print "#{stdout}"
  #STDERR.print stderr
  #STDOUT.print stdout.class #string
  #STDOUT.print stdout.scan 'AddressString'
  #$i += 1
end

puts $a.sort

Where-Object 是 PowerShell 命令而不是 Exchange 命令...

当您创建一个新的 Exchange 会话时,它只包含 Exchange Cmdlet,因此 Where-Object 不是其中之一。

您可以做的是导入会话,然后 运行 它在您当前的会话中,例如:

$username = 'username'
$password = ConvertTo-SecureString 'password'  -AsPlainText -Force
$UserCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$password
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'http://exchange.myfirm.local/PowerShell' -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session

然后运行它:

Get-Mailbox -RecipientTypeDetails 'SharedMailbox' | Get-MailboxPermission | Where-Object User -like 'anotherusername' | fl identity

这将不起作用:

Invoke-Command -Session $Session -ScriptBlock {
Get-Mailbox -RecipientTypeDetails 'SharedMailbox' | Get-MailboxPermission | Where-Object User -like 'anotherusername' | fl identity
}