Próbuję napisać skrypt PowerShell, który wyszukuje określone programy, a jeśli ich nie znajdzie, instaluje je. Używam do tego Chocolatey i wydaje się, że działa całkiem dobrze. Oto co mam do tej pory:
if (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal
.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
$tempdir = Get-Location
$tempdir = $tempdir.tostring()
$FirstAppToMatch = '*Google Earth*'
$SecondAppToMatch = '*Google Chrome*'
$ThirdAppToMatch = '*FireFox*'
$FourthAppToMatch = '*Notepad++*'
$FifthAppToMatch = '*Adobe Reader*'
$SixthAppToMatch = '*Office*'
$msiFile = $tempdir+"\microsoft.interopformsredist.msi"
$msiArgs = "-qb"
function Get-InstalledApps
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $FirstAppToMatch}
If ($result -eq $null) {
(cinst googleearthpro -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $SecondAppToMatch}
If ($result -eq $null) {
(cinst googlechrome -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $ThirdAppToMatch}
If ($result -eq $null) {
(cinst firefox -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $FourthAppToMatch}
If ($result -eq $null) {
(cinst notepadplus -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $FifthAppToMatch}
If ($result -eq $null) {
(cinst adobereader -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $SixthAppToMatch}
If ($result -eq $null) {
(cinst office365business -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Mam więc 2 problemy. Po pierwsze, wyświetla się wszystko po pierwszym „hostie zapisu”. Wiem, że mogę ukryć okno, ale nie chcę tego robić w celu testowania i debugowania mojego kodu. Próbowałem enkapsulować wszystkie polecenia hosta zapisu za pomocą {}, ale nadal pokazywał cały kod, ponieważ po uruchomieniu skryptu widzę wszystkie polecenia pokazane w oknie PS. Gdyby to była partia, po prostu wyłączałbym @echo, ale nie jestem pewien, jak to zrobić w PowerShell.
Drugi problem to bałagan. Działa, ale jest bałagan. Czuję, że powinienem być w stanie trochę skondensować ten kod, ale nie jestem pewien, jak to zrobić. W takim przypadku muszę iterować każdą aplikację, a następnie zainstalować inny program, jeśli ta konkretna „aplikacja” nie zostanie znaleziona w systemie. Poszukuje Google Earth, a jeśli go nie znajdzie, uruchamia polecenie, aby go zainstalować ... następnie powraca do następnej aplikacji ... nie znajduje go i uruchamia inne polecenie, aby zainstalować ten i tak dalej. Trafiłem jednak tym murem. Szukałem pętli i tablic, aby sprawdzić, czy mogę znaleźć lepszy sposób, niż wymienianie każdego polecenia w kółko, tak jak tutaj, ale wydaje się, że dla pętli i dla każdej pętli są przeznaczone zrobić to samo dla każdego elementu w tablicy.
Wszelkie wskazówki i porady będą mile widziane. Z góry dziękuję.
źródło