Set-Content с использованием переменных - PullRequest
0 голосов
/ 30 октября 2019

Я пытаюсь сгенерировать сценарии PowerShell, используя сценарий PowerShell. Как получить значения переменных внутри содержимого вновь сгенерированного скрипта?

foreach ($server in $testServers) {
    New-Item -ItemType File -Name "$($server)_wu.ps1" -Path "D:\tools\windows updates\uscripts"

    Set-Content -Path "D:\tools\windows updates\uscripts\$($server)_wu.ps1" -Value {
        $computer = $server

        Invoke-Command -ComputerName $computer -ScriptBlock {
            Set-ExecutionPolicy Bypass
            Find-Module PSWindowsUpdate | Install-Module -Force | Import-Module -Force
        }

        $updatesCount = (Get-WindowsUpdate -ComputerName $computer).Count

        while ($updatesCount -gt "0") {
            psexec \\$computer -s "powershell.exe "Install-WindowsUpdate -Confirm:`$false -IgnoreReboot""
            Restart-Computer -ComputerName $computer -Force -Wait
            $updatesCount = (Get-WindowsUpdate -ComputerName $computer).Count
        }
    }
}

В результате получается следующее:

$computer = $server

Invoke-Command -ComputerName $computer -ScriptBlock {
    Set-ExecutionPolicy Bypass
    Find-Module PSWindowsUpdate | Install-Module -Force | Import-Module -Force
}

$updatesCount = (Get-WindowsUpdate -ComputerName $computer).Count

while ($updatesCount -gt "0") {
    psexec \\$computer -s "powershell.exe "Install-WindowsUpdate -Confirm:`$false -IgnoreReboot""
    Restart-Computer -ComputerName $computer -Force -Wait
    $updatesCount = (Get-WindowsUpdate -ComputerName $computer).Count
}

Но в новом скрипте яХотелось бы заменить $server на имя сервера, для которого сгенерирован скрипт.

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Канонический способ сделать то, что вы просите, - это, вероятно, использовать здесь-строку и вставить определенные значения с помощью оператора формата (-f):

foreach ($server in $testServers) {
    @'
$computer = '{0}'

Invoke-Command -ComputerName $computer -ScriptBlock {
    Set-ExecutionPolicy Bypass
    Find-Module PSWindowsUpdate | Install-Module -Force | Import-Module -Force
}

$updatesCount = (Get-WindowsUpdate -ComputerName $computer).Count

while ($updatesCount -gt "0") {
    psexec \\$computer -s 'powershell.exe "Install-WindowsUpdate -Confirm:$false -IgnoreReboot"'
    Restart-Computer -ComputerName $computer -Force -Wait
    $updatesCount = (Get-WindowsUpdate -ComputerName $computer).Count
}
'@ -f $server | Set-Content -Path "D:\tools\windows updates\uscripts\${server}_wu.ps1"
}

Однако я бы сказал, что написание одного параметризованного сценария и вызов его с соответствующим именем компьютера может быть более подходящим решением, чем создание одного сценария для каждого компьютера:

[CmdletBinding()]
Param(
    [Parameter(Mandatory=$true)]
    [string]$Computer
)

Invoke-Command -ComputerName $Computer -ScriptBlock {
    Set-ExecutionPolicy Bypass
    Find-Module PSWindowsUpdate | Install-Module -Force | Import-Module -Force
}

$updatesCount = (Get-WindowsUpdate -ComputerName $Computer).Count

while ($updatesCount -gt "0") {
    psexec \\$Computer -s 'powershell.exe "Install-WindowsUpdate -Confirm:$false -IgnoreReboot"'
    Restart-Computer -ComputerName $Computer -Force -Wait
    $updatesCount = (Get-WindowsUpdate -ComputerName $Computer).Count
}

Вызов:

PS> <b>script.ps1 -Computer FOO</b>
0 голосов
/ 30 октября 2019

Хорошо - поэтому я не мог понять, как манипулировать моей строкой, и в итоге решил ее так ... Любой более короткий и простой ответ абсолютно приветствуется (обратите внимание, что остальная часть сценария также немного изменилась)

foreach ($server in $testServers) {

    New-Item -ItemType File -Name "$($server)_wu.ps1" -Path "\\VILV12ICTSCRIPT\d$\windowsupdates\uscripts"

    $value = '

    $computer = $PSCommandPath
    $computer = $computer.Split("`\")[3]
    $computer = $computer.Split("_")[0]

    Invoke-Command -ComputerName $computer -ScriptBlock {

        Set-ExecutionPolicy Bypass
        Find-Module PSWindowsUpdate | Install-Module -Force | Import-Module -Force

    }

    $updatesCount = (PsExec.exe \\$computer -s "powershell.exe "Get-WindowsUpdate"").Count

    while ($updatesCount -gt "0") {

        psexec \\$computer -s "powershell.exe "Install-WindowsUpdate -Confirm:`$false -IgnoreReboot""
        Restart-Computer -ComputerName $computer -Force -Wait
        $updatesCount = (PsExec.exe \\$computer -s "powershell.exe "Get-WindowsUpdate"").Count

    }

    Write-Host "No more updates available for $($computer)" -BackgroundColor DarkGreen

    '

    Set-Content -Path "\\VILV12ICTSCRIPT\d$\windowsupdates\uscripts\$($server)_wu.ps1" -Value $value

}

И сгенерированный скрипт, и сгенерированные скрипты работают как талисманы (^^,)

Cheers

...