【发布时间】:2019-03-31 14:52:07
【问题描述】:
我的任务是编写一个 PS 脚本,该脚本将从文本文件中的机器列表中:
- 输出机器的IP地址
- 获取机器上的 SCCM 客户端版本
- 生成 GPResult HTMl 文件 或
- 表示机器离线
最后规定在后台运行脚本(Job)
我拥有可以完成所有这些事情的脚本块,甚至可以按照我的意愿设置输出格式。我不能似乎做的是让脚本块从与脚本相同的目录中调用源文件。我意识到我可以简单地对目录进行硬编码,但我希望能够在任何机器上的任何目录中运行它,因为我需要在多个位置使用脚本。
有什么建议吗?
代码如下(注意:我正在尝试从其他文章中收集的东西,所以它有一个或两个片段[最近的尝试是指定工作目录],但核心代码仍然是那里。我也有想法首先声明脚本块,就像你在其他编程语言中处理变量一样,但更多的是为了可读性):
# List of commands to process in job
$ScrptBlk = {
param($wrkngdir)
Get-Content Hostnames.txt | ForEach-Object {
# Check to see if Host is online
IF ( Test-Connection $_ -count 1 -Quiet) {
# Get IP address, extracting only IP value
$addr = (test-connection $_ -count 1).IPV4Address
# Get SCCM version
$sccm = (Get-WmiObject -NameSpace Root\CCM -Class Sms_Client).ClientVersion
# Generate GPResult HTML file
Get-GPResultantSetOfPolicy -computer $_.name -reporttype HTML -path ".\GPRes\$_ GPResults.html"}
ELSE {
$addr = "Offline"
$sccm = " "}
$tbl = New-Object psobject -Property @{
Computername = $_
IPV4Address = $addr
SCCM_Version = $sccm}}}
# Create (or clear) output file
Echo "" > OnlineCheckResults.txt
# Create subdirectory, if it does not exist
IF (-Not (Get-Item .\GPRes)) { New-Item -ItemType dir ".\GPRes" }
# Get current working directory
$wrkngdir = $PSScriptRoot
# Execute script
Start-Job -name "OnlineCheck" -ScriptBlock $ScrptBlk -ArgumentList $wrkngdir
# Let job run
Wait-Job OnlineCheck
# Get results of job
$results = Receive-Job OnlineCheck
# Output results to file
$results >> OnlineCheckResults.txt | FT Computername,IPV4Address,SCCM_Version
感谢您提供的任何帮助。
干杯。
~大卫M~
编辑
感谢所有帮助。设置工作目录有效,但我现在收到一个新错误。它没有行参考,所以我不确定问题可能出在哪里。新代码如下。我已将 sriptblock 移至底部,因此它与其余代码是分开的。我认为这可能会更整洁一些。我为我之前的代码格式道歉。我将尝试在新示例中做得更好。
# Store working directory
$getwkdir = $PWD.Path
# Create (or clear) output file
Write-Output "" > OnlineCheckResults.txt
# Create subdirectory, if it does not exist. Delete and recreate if it does
IF (Get-Item .\GPRes) {
Remove-Item -ItemType dir "GPRes"
New-Item -ItemType dir "GPRes"}
ELSE{
New-Item -ItemType dir "GPRes"}
# Start the job
Start-Job -name "OnlineCheck" -ScriptBlock $ScrptBlk -ArgumentList $getwkdir
# Let job run
Wait-Job OnlineCheck
# Get results of job
$results = Receive-Job OnlineCheck
# Output results to file
$results >> OnlineCheckResults.txt | FT Computername,IPV4Address,SCCM_Version
$ScrptBlk = {
param($wrkngdir)
Set-Location $wrkngdir
Get-Content Hostnames.txt | ForEach-Object {
IF ( Test-Connection $_ -count 1 -Quiet) {
# Get IP address, extracting only IP value
$addr = (test-connection $_ -count 1).IPV4Address
# Get SCCM version
$sccm = (Get-WmiObject -NameSpace Root\CCM -Class Sms_Client).ClientVersion
Get-GPResultantSetOfPolicy -computer $_.name -reporttype HTML -path ".\GPRes\$_ GPResults.html"}
ELSE {
$addr = "Offline"
$sccm = " "}
$tbl = New-Object psobject -Property @{
Computername = $_
IPV4Address = $addr
SCCM_Version = $sccm}}}
错误文本: 无法验证参数“ComputerName”上的参数。参数为 null 或空。提供一个论据 不为 null 或为空,然后重试该命令。 + CategoryInfo : InvalidData: (:) [Test-Connection], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand + PSComputerName : 本地主机
【问题讨论】:
-
乍一看,您没有使用您在
-ArgumentLIst中发送的$wrkngdir参数。Get-Content (Join-Path -Path $wrkngdir -ChildPath 'Hostnames.txt')怎么样。另外,如果我可以建议,请对您的代码缩进做一些事情,因为现在它真的很难阅读.. -
可能有助于开始在 PowerShell 高级功能的概念中思考和设计脚本。使用 Begin、Process、End 块。在 PowerShell ISE 中,CTRL + J 打开 sn-ps 并插入以查看示例。
标签: powershell working-directory start-job