[英]Powershell script to install multiple applications using an array and scriptblock
Need help troubleshooting an the Array and Scriptblock OR Maybe this is better using param and functions???需要帮助解决 Array 和 Scriptblock 问题,或者使用参数和函数可能更好???
Script Objective: To easily update the list of applications to be installed脚本目标:轻松更新要安装的应用程序列表
Getting error below.在下面出现错误。
' At C:\Temp\appinstall.ps1:7 char:10 $Firefox={ ' 在 C:\Temp\appinstall.ps1:7 char:10 $Firefox={
~ The assignment expression is not valid. ~ 赋值表达式无效。 The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.赋值运算符的输入必须是能够接受赋值的 object,例如变量或属性。 + CategoryInfo: ParserError: (:) [], ParseException + FullyQualifiedErrorId: InvalidLeftHandSide ' + CategoryInfo: ParserError: (:) [], ParseException + FullyQualifiedErrorId: InvalidLeftHandSide '
Start-Transcript -Append c:\Deploy\log.txt
$ProgressPreference = 'SilentlyContinue';
#Change App Name, Source, MSI/EXE, Argument
$AppArray= (
$Firefox={
$App= "Firefox";
$App_source= "https://download.mozilla.org/?product=firefox-latest&os=win64&lang=en-US";
$destination = "c:\Deploy\$App.exe";
$Argument= "/S";
},
$Chrome=
{
$App= "Chrome";
$App_source= "https://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi";
$destination = "c:\Deploy\$App.exe";
$Argument= "/norestart","/qn";
}
)
$InstallScriptBlock=
{
$installed = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -Match "$App" });
$installed.displayname
if ($installed.displayname -Match $App) {
Write-Host "$software installed"
}else{
If ((Test-Path $destination) -eq $false) {
New-Item -ItemType File -Path $destination -Force
}
#install software
Invoke-WebRequest $App_source -OutFile $destination
Start-Process -FilePath "$destination" -ArgumentList "$Argument" -Wait
#Delete installer
Remove-Item -recurse "$destination"
}
}
ForEach ($Program in $AppArray) {Invoke-Command -ScriptBlock $InstallScriptBlock}
Stop-Transcript
It looks like you're trying to create a nested hashtable ( @{... }
), but your syntax is flawed - see the linked docs.看起来您正在尝试创建一个嵌套的哈希表( @{... }
),但您的语法有缺陷 - 请参阅链接文档。
However:然而:
It should suffice in your case to create an array of hashtables to iterate over with foreach
在您的情况下,创建一个哈希表数组以使用foreach
进行迭代就足够了
There's no need to use a separate script block ( {... }
) - just use the body of the foreach
loop statement.无需使用单独的脚本块( {... }
) - 只需使用foreach
循环语句的主体即可。
Invoke-Command
for local invocation of script blocks works, it usually isn't necessary, because &
, the call operator , will do (eg $sb = { 'hi' }; & $sb
).顺便说一句:虽然使用Invoke-Command
来本地调用脚本块是可行的,但通常没有必要,因为&
, 调用运算符,会这样做(例如$sb = { 'hi' }; & $sb
)。 Invoke-Command
's primary purpose is to execute a script block on a remote machine . Invoke-Command
的主要目的是在远程机器上执行脚本块。 Generally, you can use variables as-is as command arguments, without enclosing them in "..."
- even if their values contain spaces.通常,您可以按原样使用变量作为命令 arguments,无需将它们括在"..."
中 - 即使它们的值包含空格。 Eg, Write-Output $foo
is sufficient, no need for Write-Output "$foo"
例如, Write-Output $foo
就足够了,不需要Write-Output "$foo"
To put it all together:把它们放在一起:
# Create an array whose elements are hashtables.
$appArray = (
@{
App = ($thisApp = 'Firefox')
App_source = 'https://download.mozilla.org/?product=firefox-latest&os=win64&lang=en-US'
Destination = "c:\Deploy\$thisApp.exe"
Argument = '/S'
},
@{
App = ($thisApp = 'Chrome')
App_source = 'https://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi'
Destination = "c:\Deploy\$thisApp.exe"
Argument = '/norestart /qn'
}
)
foreach ($app in $appArray) {
# Note how $app.<key> is used to refer to the entries of the hashtable at hand,
# e.g. $app.App yields "Firefox" for the first hashtable.
$installed = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -Match $app.App }
$installed.displayname
if ($installed.displayname -Match $app.App) {
Write-Host "$($app.App) already installed."
}
else {
if ((Test-Path $app.Destination) -eq $false) {
New-Item -ItemType File -Path $app.Destination -Force
}
#install software
Invoke-WebRequest $app.App_source -OutFile $app.Destination
Start-Process -FilePath $app.Destination -ArgumentList $app.Argument -Wait
#Delete installer
Remove-Item -Recurse $app.Destination
}
}
Note:笔记:
I've removed unnecessary ;
我删除了不必要的;
and I've switched to using verbatim (single-quoted) strings ( '...'
) when no string interpolation via expandable (double-quoted) strings ( "..."
) is required, both for conceptual clarity and to avoid potentially unwanted expansions.当不需要通过可扩展(双引号)字符串( "..."
)进行字符串插值时,我已经切换到使用逐字(单引号)字符串( '...'
),这既是为了概念清晰,也是为了避免可能不需要的扩展。
Note the use of aux.注意辅助的使用。 variable $thisApp
in the App
key, which allows referencing it in the later Destination
key, in an expandable string ( "c:\Deploy\$thisApp.exe"
). App
键中的变量$thisApp
,允许在后面的Destination
键中以可扩展字符串 ( "c:\Deploy\$thisApp.exe"
) 引用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.