下面是一个示例脚本,尝试在服务器上创建远程会话,然后使用WMI获取服务器的IIS应用程序池列表,并列出其名称:
function Test-Remoting
{
[CmdletBinding()]
param
(
)
begin
{
Enter-PSSession TestServer
$appPools = Get-WmiObject -namespace "root\MicrosoftIISv2" -class "IIsApplicationPool" -Authentication 6
$appPools | ForEach-Object {
$appPool = $_;
$appPool.Name
}
Exit-PSSession
}
}
Run Code Online (Sandbox Code Playgroud)
此函数包含在名为"Test-Remoting.ps1"的文件中.我将PowerShell,CD打开到包含该文件的目录中,将该文件点源,并调用该函数:
PS C:\Users\moskie> . .\Test-Remoting.ps1
PS C:\Users\moskie> Test-Remoting
Run Code Online (Sandbox Code Playgroud)
但是此脚本的结果是我本地计算机上的应用程序池列表,而不是 TestServer.
或者,如果我在PowerShell提示符下手动运行以下行(与函数中的行相同),我会获取远程服务器上的应用程序池列表:
PS C:\Users\moskie> Enter-PSSession TestServer
[TestServer]: PS C:\> $appPools = Get-WmiObject -namespace "root\MicrosoftIISv2" -class "IIsApplicationPool" -Authentication 6
[TestServer]: PS C:\> $appPools | ForEach-Object { $appPool = $_; $appPools.Name }
<a list of …Run Code Online (Sandbox Code Playgroud) 我使用powershell来检查我的计算机上是否打开了端口.我有8台Windows 2008 R2机器,我运行以下脚本:
$localhost = get-content env:computername
foreach($port in get-content "\\computer1\txtfiles\ports.txt")
{
foreach ($hostname in get-content "\\compiuter1\txtfiles\servers.txt")
{
try {
$sock = new-object System.Net.Sockets.Socket -ArgumentList $([System.Net.Sockets.AddressFamily]::InterNetwork),$([System.Net.Sockets.SocketType]::Stream),$([System.Net.Sockets.ProtocolType]::Tcp)
$sock.Connect($hostname,$Port)
$output = $localhost+","+$hostname+","+$port+","+$sock.Connected
$output
$sock.Close()
}
catch {
$output = $localhost+","+$hostname+","+$port+","+$sock.Connected
$output
}
}
Run Code Online (Sandbox Code Playgroud)
}
我在计算机1的8台计算机上运行此脚本,使用:
Invoke-Command -ComputerName computer1,computer2 -FilePath F:\scripts\port-test.ps1
Run Code Online (Sandbox Code Playgroud)
在第一台计算机上(计算机1 - 我执行脚本的机器)我得到了一个输出但是在计算机上我得到了:
Cannot find path '\\computer1\txtfiles' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\computer1\txt
files:String) [Set-Location], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
Run Code Online (Sandbox Code Playgroud)
为什么Powershell不会看到网络共享?我该如何解决?
使用从Microsoft找到的库,我一直在尝试(使用C#)使用Live @ Edu为我的用户设置电子邮件帐户,并且该库使用远程PowerShell会话来执行此操作。我已经用using() { }模拟本地管理员帐户的块包装了PowerShell调用。当我在自己的开发机器上运行代码时,它可以很好地运行并在Live @ Edu上配置该帐户,但是当我在生产服务器上运行相同的代码时,我Access is Denied从PowerShell中得到了一个错误。
我刚刚注意到的是,如果我将服务器上的IIS应用程序池用户更改为自己的域帐户,则在生产服务器上一切正常,但将其保留为ApplicationPoolIdentity无效。因此看来,即使在我的代码中我扮演了本地管理员的角色,这些凭据也没有传递给PowerShell会话。奇怪的是,当脚本在我自己的计算机上(也位于)下运行时ApplicationPoolIdentity,没有问题,这使我相信脚本实际上是在我的计算机上以我自己的帐户运行的(并且我是本地管理员)。
我确实让代码吐出了的值,$env:username它给了我机器名称,我希望它能给我提供运行它的实际用户名,因为那是我直接在PowerShell窗口中键入该命令时得到的。
当使用我一直在代码中模拟的凭据交互式登录到远程服务器时,我可以在PowerShell窗口中手动键入所有PowerShell cmdlt,它们可以正常工作。
我不想让我的IIS应用程序池始终在管理员帐户下运行,因为这样做看起来很愚蠢,所以有没有办法以比我目前的模拟更进一步的方式运行PowerShell脚本作为管理员?
更新:
发生了一件奇怪的事情,似乎对我来说是一个解决方案。将代码部署到服务器后,我创建了一个本地管理员帐户。然后,我进入IIS应用程序池,并将所有者从更改为ApplicationPoolIdentity刚创建的管理帐户。之后,该页面可以正常运行PowerShell脚本。我以前就已经知道这一点,但是不想让IIS使用管理员帐户。然后,我继续将应用程序池设置回ApplicationPoolIdentity并删除了本地管理员帐户,该页面仍然有效!我重新启动了IIS,然后重新启动了Web服务器本身,一切正常。我能想到的是,将应用程序池移至管理员帐户会永久更改应用程序池中的某些属性。我现在在ServerFault上提出了一个修改后的问题。
我有这个数组(简化):
$v = 3,5,3,6,8,3,5,7
Run Code Online (Sandbox Code Playgroud)
我需要检查所有值是否都高于 3。我认为 Foreach 或 Foreach-Object 将适合此任务,但我无法弄清楚它的工作方式。
我已经尝试过类似的方法,但它不起作用。
$v | Foreach-Object (if($_ -lt 10){Write-Host "$_ lt 10"})
Run Code Online (Sandbox Code Playgroud)
编辑:
感谢你们!我将声明更改为:
$v | Foreach-Object {if($_ -lt 10){$check_value = "True"}}
Run Code Online (Sandbox Code Playgroud)
它现在正在工作,但我刚刚意识到,简单化的数组不是一个好主意。我使用的数组中的数据是从 MS SQL 数据库中获取的。如果我在屏幕上显示数组,我会得到数字,但数据类型是 System.Data.DataRow,我无法将其与数字进行比较。我收到错误消息:
Bad argument to operator '-lt': Could not compare "System.Data.DataRow" to "95". Error: "Cannot convert the "95" value of type "System.Int32" to type "System.Data.DataRow".".
Run Code Online (Sandbox Code Playgroud)
编辑2:
飞溅的碎片:
我正在使用您的代码,一切正常,但我无法通过此比较:
$rowsGreaterThanThree.Count -eq $v.Count
Run Code Online (Sandbox Code Playgroud)
$rowsGreaterThanThree 的值为:
0.00127998361620918
1.53972183002211
0.00127998361620918 0.00127998361620918
0.00127998361620918
1.53972183002211
0.0012799
8361620918
0.00127998361620918
0.00127998361620918
3.1262399841282
0
0 …
我正在尝试并行从Office 365 Exchange Online中提取数据以节省时间.我无法完成我想要做的事,下面的代码是我到目前为止"最接近"的代码.
Workflow Get-MailboxStatisticsParallel{
param ($o365cred)
$session = InlineScript {
New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/" -Credential $using:o365cred -Authentication Basic -AllowRedirection
}
InlineScript {
Invoke-Command -Session $session -ScriptBlock {Get-Mailbox "Firstname Middleinitial. Lastname"}
}
}
Run Code Online (Sandbox Code Playgroud)
我定义了两个内联脚本,因为我想设置一次远程会话,然后并行调用Get-Mailbox命令以加快进程.以下是我希望工作流程看起来像的示例.
Workflow Get-MailboxStatisticsParallel{
param ($o365cred, $mailboxes)
$session = InlineScript {
New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/" -Credential $using:o365cred -Authentication Basic -AllowRedirection
}
ForEach -Parallel ($mailbox in $mailboxes){
InlineScript {
Invoke-Command -Session $using:session -ScriptBlock {param ($mailbox); Get-MailboxStatistics $mailbox.UserPrincipalName} -ArgumentList $mailbox
}
}
}
Run Code Online (Sandbox Code Playgroud)
示例运行将如下所示.
$cred = Get-Credential …Run Code Online (Sandbox Code Playgroud) powershell workflow powershell-remoting office365 powershell-3.0
我正在尝试通过 Windows Powershell 从远程 Exchange 服务器接收所有 TransportAgent 的状态。
我偶尔会收到一个错误,即The session state is Broken. 一旦它坏了,我需要创建一个新的会话
下面是我正在使用的命令列表(按正确顺序)
# Build the PSSession for Exchange
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<SERVER>/PowerShell/ -Authentication Default
# Invoke the command 'Get-TransportAgent' on the remote PSSession
Invoke-Command $Session {Get-TransportAgent}
# Result when there is NO ERROR
Identity Enabled Priority PSComputerName
-------- ------- -------- --------------
Transport Rule Agent True 1 <SERVER>
Malware Agent True 2 <SERVER>
Text Messaging Routing Agent True 3 <SERVER>
Text Messaging Delivery …Run Code Online (Sandbox Code Playgroud) 我正在尝试运行以下命令
$secpasswd = 'Test'
$secpasswd = ConvertTo-SecureString $secpasswd -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ('domain2\nick', $secpasswd)
[scriptblock]$CheckDNS = {
Get-DnsServerResourceRecord -Name 'computername' -ZoneName domain2.local -ComputerName domain2dC.domain2.local }
invoke-command -scriptblock $CheckDNS -Credential $mycreds -ComputerName domain2managementbox.domain2.local
Run Code Online (Sandbox Code Playgroud)
这应该在目标计算机上运行 Get-DnsServerResourceRecord 模块,但是我收到以下错误:
Failed to get the zone information for domain2.local on server domain2managementbox.domain2.local.
+ CategoryInfo : PermissionDenied: (dgtest.local:root/Microsoft/...rResourceRecord) [Get-DnsServerResourceRecord], CimException
+ FullyQualifiedErrorId : WIN32 5,Get-DnsServerResourceRecord
Run Code Online (Sandbox Code Playgroud)
当我在盒子本身上运行命令时,它工作正常并且我拥有正确的权限。
谢谢
我有一个位于远程系统上的脚本。
在服务器“web12”上的 C:\tmp\hgttg.ps1 下:
Write-Host "Don't Panic"
exit 42
Run Code Online (Sandbox Code Playgroud)
我使用 Invoke-Command 从本地机器(两个系统都运行 v4.0)调用此脚本:
$svr = "web12"
$cmd = "C:\tmp\hgttg.ps1"
$result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd}
Run Code Online (Sandbox Code Playgroud)
执行时会产生以下输出:
> $result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd}
Don't Panic
> $result
>
Run Code Online (Sandbox Code Playgroud)
($result未设置,输出直接到控制台,不好!)经过大量的网络搜索和故障排除,我得到了一些改进:
> $result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd; $LASTEXITCODE}
Don't Panic
> $result
42
>
Run Code Online (Sandbox Code Playgroud)
现在我可以捕获返回代码,但输出仍然直接发送到控制台。这是我所能得到的。在我已经尝试过的一长串事情中,以下任何一项都不起作用:
这会产生输出:
> $result
code : 42
output :
PSComputerName : web12 …Run Code Online (Sandbox Code Playgroud) powershell exit-code powershell-remoting powershell-4.0 write-host
我可以在特定的计算机上执行以下命令,它可以返回多个目标计算机上的进程列表,但在一台计算机上返回"无法连接到远程计算机"错误.
get-process -ComputerName 192.168.1.101
什么会阻止我使用PowerShell从远程计算机获取进程列表?
我有一台运行Windows Server 2012 R2的2台服务器.其中一个是托管运行Windows 7 32位的虚拟机,我正在尝试使用其他服务器来查看当前正在运行的虚拟机进程.
我不得不使用Enable-PSRemoting -SkipNetworkProfileCheck来完成任何工作.我还必须将计算机添加到彼此TrustedHosts列表中.
Get-Process -ComputerName VM01
Run Code Online (Sandbox Code Playgroud)
将返回"无法连接到远程计算机".然而,
Invoke-Command -ComputerName VM01 -ScriptBlock {Get-Process}
Run Code Online (Sandbox Code Playgroud)
工作得很好.使用Invoke-Command和将Get-Process与ComputerName参数一起使用有什么区别?如果它很重要,我也可以毫无问题地使用Enter-PSSession