我对PowerShell比较陌生,并且有一个脚本可以读取一个配置文件,该文件会产生一组名称值对,我希望将它们作为参数传递给第二个PowerShell脚本中的函数.
我不知道在设计时将在此配置文件中放置哪些参数,所以就在我需要调用第二个PowerShell脚本时,我基本上只有一个变量具有第二个脚本的路径,第二个脚本变量,它是要传递给路径变量中标识的脚本的参数数组.
因此,包含第二个脚本($ scriptPath)路径的变量可能具有如下值:
"c:\the\path\to\the\second\script.ps1"
Run Code Online (Sandbox Code Playgroud)
包含参数($ argumentList)的变量可能类似于:
-ConfigFilename "doohickey.txt" -RootDirectory "c:\some\kind\of\path" -Max 11
Run Code Online (Sandbox Code Playgroud)
如何从这种状态到使用$ argumentList中的所有参数执行script.ps1?
我希望来自第二个脚本的任何write-host命令对于调用此第一个脚本的控制台是可见的.
我尝试过dot-sourcing,Invoke-Command,Invoke-Expression和Start-Job,但我还没有找到一种不会产生错误的方法.
例如,我认为最简单的第一条路线是尝试按如下方式调用Start-Job:
Start-Job -FilePath $scriptPath -ArgumentList $argumentList
Run Code Online (Sandbox Code Playgroud)
...但是由于此错误而失败:
System.Management.Automation.ValidationMetadataException:
Attribute cannot be added because it would cause the variable
ConfigFilename with value -ConfigFilename to become invalid.
Run Code Online (Sandbox Code Playgroud)
...在这种情况下,"ConfigFilename"是第二个脚本定义的参数列表中的第一个参数,我的调用显然试图将其值设置为"-ConfigFilename",这显然是为了按名称标识参数,没有设定它的价值.
我错过了什么?
编辑:
好的,这是一个名为invokee.ps1的文件中的待调用脚本的模型
Param(
[parameter(Mandatory=$true)]
[alias("rc")]
[string]
[ValidateScript( {Test-Path $_ -PathType Leaf} )]
$ConfigurationFilename,
[alias("e")]
[switch]
$Evaluate,
[array]
[Parameter(ValueFromRemainingArguments=$true)]
$remaining)
function sayHelloWorld()
{
Write-Host "Hello, everybody, the config file is <$ConfigurationFilename>."
if ($ExitOnErrors)
{
Write-Host "I should …
Run Code Online (Sandbox Code Playgroud) powershell parameter-passing command-line-arguments invoke-command start-job
有没有办法为Start-Job命令指定工作目录?
用例:
我在一个目录中,我想用Emacs打开一个文件进行编辑.如果我直接执行此操作,它将阻止PowerShell,直到我关闭Emacs.但是使用Start-Job尝试从我的主目录运行Emacs,从而让Emacs打开一个新文件而不是我想要的文件.
我尝试使用$ pwd指定完整路径,但脚本块中的变量在Start-Job上下文中执行之前不会被解析.因此,强制解决shell上下文中的变量的一些方法也是可接受的答案.
所以,这是我尝试过的,只是为了完整性:
Start-Job { emacs RandomFile.txt }
Start-Job { emacs "$pwd/RandomFile.txt" }
Run Code Online (Sandbox Code Playgroud) 在powershell中,我想学习将变量调用到起始作业的最佳方法,因此我不必编辑每个服务器的脚本,因为它将基于我放置脚本的客户端而具体.
$Servername = 'Server1'
$pingblock = {
pathping $servername | Out-File C:\client\PS\ServerPing.TXT
}
start-job $pingblock
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,我只是得到一个帮助文件,好像我忘了指定$ servername.
我想在Powershell中使用后台作业.
如何在ScriptBlock定义时评估变量?
$v1 = "123"
$v2 = "asdf"
$sb = {
Write-Host "Values are: $v1, $v2"
}
$job = Start-Job -ScriptBlock $sb
$job | Wait-Job | Receive-Job
$job | Remove-Job
Run Code Online (Sandbox Code Playgroud)
我得到$ v1和$ v2的空值.如何让它们在(通过)脚本块中进行评估,从而对后台作业进行评估?
概观
想要调用带有参数的Powershell脚本,在后台运行每个作业,并向我显示详细输出.
我遇到的问题
该脚本似乎正在运行,但我希望通过在后台作业运行时流式传输结果来确认这一点.
码
###StartServerUpdates.ps1 Script###
#get list of servers to update from text file and store in array
$servers=get-content c:\serverstoupdate.txt
#run all jobs, using multi-threading, in background
ForEach($server in $servers){
Start-Job -FilePath c:\cefcu_it\psscripts\PSPatch.ps1 -ArgumentList $server
}
#Wait for all jobs
Get-Job | Wait-Job
#Get all job results
Get-Job | Receive-Job
Run Code Online (Sandbox Code Playgroud)
我目前看到的是:
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
23 Job23 Running True localhost #patch server ...
25 Job25 Running True localhost #patch server …
Run Code Online (Sandbox Code Playgroud) 所以情况就是这样:我在脚本(.ps1)文件中有两个函数DoWork和DisplayMessage.这是代码:
### START OF SCRIPT ###
function DoWork
{
$event = Register-EngineEvent -SourceIdentifier NewMessage -Action {
DisplayMessage($event.MessageData)
}
$scriptBlock = {
Register-EngineEvent -SourceIdentifier NewMessage -Forward
$message = "Starting work"
$null = New-Event -SourceIdentifier NewMessage -MessageData $message
### DO SOME WORK HERE ###
$message = "Ending work"
$null = New-Event -SourceIdentifier NewMessage -MessageData $message
Unregister-Event -SourceIdentifier NewMessage
}
DisplayMessage("Processing Starts")
$array = @(1,2,3)
foreach ($a in $array)
{
Start-Job -Name "DoActualWork" $ScriptBlock -ArgumentList $array | Out-Null …
Run Code Online (Sandbox Code Playgroud) 我想降低我在PowerShell脚本中使用Start-Job开始的作业的优先级.这可能吗?
我在Start-Job中使用Start-Process时遇到问题,特别是在使用时-NoNewWindow
.例如,这个测试代码:
Start-Job -scriptblock {
Start-Process cmd -NoNewWindow -Wait -ArgumentList '/c', 'echo' | out-null
Start-Process cmd # We'll never get here
}
get-job | wait-job | receive-job
get-job | remove-job
Run Code Online (Sandbox Code Playgroud)
返回以下错误,显然谷歌没有听说过:
Receive-Job:处理来自后台进程的数据时出错.报告错误:无法处理节点类型为"Text"的元素.仅支持Element和EndElement节点类型.
如果我删除-NoNewWindow
一切工作就好了.我做的事情愚蠢,还是没有办法开始工作Start-Process -NoNewWindow
?有什么好的选择?
我需要调用几十万个URL.这些是对应用程序服务器的调用,应用程序服务器将处理它们并将状态代码写入表.我不需要等待响应(成功/失败),只需要服务器获得请求.我还希望能够指定一次可以运行多少并发作业,因为我还没有确定tomcat可以处理多少并发请求.
这是我到目前为止所得到的,基本上取自某人的其他人尝试做类似的事情,而不是使用网址调用.文本文件包含各自的URL.网址如下所示:
http://webserver:8080/app/mwo/services/create?server=ServerName&e1user=admin&newMWONum=123456&sourceMWONum=0&tagNum=33-A-1B
Run Code Online (Sandbox Code Playgroud)
和代码:
$maxConcurrentJobs = 10
$content = Get-Content -Path "C:\Temp\urls.txt"
foreach ($url in $content) {
$running = @(Get-Job | Where-Object { $_.State -eq 'Running' })
if ($running.Count -le $maxConcurrentJobs) {
Start-Job {
Invoke-WebRequest -UseBasicParsing -Uri $using:url
}
} else {
$running | Wait-Job -Any
}
Get-Job | Receive-Job
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是每个"工作"给出2个错误,我不知道为什么.当我转储url数组$ content时,它看起来很好,当我逐个运行我的Invoke-WebRequest时,它们可以正常工作.
126 Job126 BackgroundJob Running True localhost ...
Invalid URI: The hostname could not be parsed.
+ CategoryInfo : NotSpecified: (:) [Invoke-RestMethod], UriFormatException
+ FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeRestMethodComman
d …
Run Code Online (Sandbox Code Playgroud) 请查看此测试脚本以及我对“Receive-Job”如何工作的详细结论。
我仍然有问题需要弄清楚,“接收作业”是如何从代码块中提取流的。
<# .SYNOPSIS Test the console output and variable capturing of Write- cmdlet calls in a code block used by 'Start-Job'
.NOTES
.NET Version 4.7.2
PSVersion 5.1.16299.431
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.16299.431
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
#>
Set-StrictMode -Version latest
if ($host.Name -inotmatch 'consolehost') { Clear-Host }
$errorBuffer = $null
$warningBuffer = $null
$outBuffer = $null
$infoBuffer = $null
# Start the job
$job = Start-Job -ScriptBlock {
Set-StrictMode -Version latest …
Run Code Online (Sandbox Code Playgroud) powershell ×10
start-job ×10
asynchronous ×1
background ×1
jobs ×1
scriptblock ×1
variables ×1