提问人:The Nurse 提问时间:8/27/2021 更新时间:8/27/2021 访问量:82
启动从服务器到远程计算机的 powersehell 脚本
Launch powersehell script from server to remote computer
问:
我正在尝试将命令从服务器发送到计算机,这些命令将启动网络共享中的powershell脚本。
我尝试启动的脚本必须用于更新某些内容,但它显示 à 进度条以查看启动脚本中操作的演变。
我想做的是我想将该脚本启动到计算机,但我想从我的服务器查看进度条状态(用户将一无所获),winrm 已启用,我使用此命令从远程启动脚本:
$machine = computer01
$script = {
param($Global:SCCM)
& "\\$Global:SCCM\MajPoliciesSCCM.ps1"
}
Invoke-Command -ComputerName $machine -ScriptBlock $script -ArgumentList $Global:SCCM
$Global:SCCM 是包含 powershell 脚本(带进度条)的服务器的变量。
我不知道是否可以从我的服务器看到进度条状态,因为我认为如果脚本启动到我的计算机 01,该状态将出现在这台机器上。
有可能这样做吗?
这是我的带有进度条的代码:
#Assembly.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Global:syncHash = [hashtable]::Synchronized(@{})
$newRunspace =[runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
# Load WPF assembly if necessary
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
$psCmd = [PowerShell]::Create().AddScript({
[xml]$xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Mise à jours des stratégies du client SCCM" Height="350" Width="525">
<Grid Background="#68BFDD">
<TextBlock x:Name="textBlock" HorizontalAlignment="center" Height="62" Margin="30" TextWrapping="Wrap" Text="Barre de progression" FontWeight="Bold" UseLayoutRounding="True" VerticalAlignment="Top" Width="200" Foreground="White" FontSize="18.667"/>
<Button x:Name="button" Content="Exécuter" FontWeight="Bold" HorizontalAlignment="Left" Height="50" Margin="322,-60,0,0" Width="114">
<Button.Effect>
<DropShadowEffect BlurRadius="15" ShadowDepth="0"/>
</Button.Effect>
<Button.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="5"/>
<Setter Property="Padding" Value="10,2,10,3"/>
<Setter Property="Background" Value="White"/>
</Style>
</Button.Resources>
</Button>
<Button x:Name="button2" Content="Fermer" FontWeight="Bold" HorizontalAlignment="Left" Height="50" Margin="322,100,0,0" Width="114" Style="{DynamicResource RoundCorner}" IsCancel="True" Command="{Binding CloseWindowCommand, Mode=OneWay}" CommandParameter="{Binding ElementName=TestWindow}">
<Button.Effect>
<DropShadowEffect BlurRadius="15" ShadowDepth="0"/>
</Button.Effect>
<Button.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="5"/>
<Setter Property="Padding" Value="10,2,10,3"/>
<Setter Property="Background" Value="White"/>
</Style>
</Button.Resources>
</Button>
<ProgressBar x:Name = "ProgressBar" Height = "20" Width = "400" HorizontalAlignment="Left" VerticalAlignment="Top" Margin = "36,270,0,0"/>
<TextBlock x:Name="heartbeat" HorizontalAlignment="Left" Height="23" Margin="10,108,0,0" VerticalAlignment="Top" Width="161" FontSize="12" FontWeight="Bold" >
Lancement du HeartBeat
</TextBlock>
<TextBlock x:Name="startordieval" HorizontalAlignment="Left" Height="35" Margin="10,136,0,0" VerticalAlignment="Top" Width="201" FontSize="12" FontWeight="Bold" >
Strategie ordinateur et cycle <LineBreak/> d'évaluation
</TextBlock>
<TextBlock x:Name="cycleEvalLog" HorizontalAlignment="Left" Height="23" Margin="10,175,0,0" VerticalAlignment="Top" Width="240" FontSize="12" FontWeight="Bold" >
Déploiements de mises à jours logiciels
</TextBlock>
<TextBlock x:Name="cycleevalappli" HorizontalAlignment="Left" Height="35" Margin="10,200,0,0" VerticalAlignment="Top" Width="161" FontSize="12" FontWeight="Bold" >
Cycle d'evaluation du <LineBreak/>déploiement de l'application
</TextBlock>
<TextBlock x:Name="EndScript" HorizontalAlignment="Left" Height="23" Margin="10,240,0,0" TextWrapping="Wrap" Text="Fin du script" VerticalAlignment="Top" Width="111" FontSize="12" FontWeight="Bold"/>
</Grid>
</Window>
"@
# Remove XML attributes that break a couple things.
# Without this, you must manually remove the attributes
# after pasting from Visual Studio. If more attributes
# need to be removed automatically, add them below.
$AttributesToRemove = @(
'x:Class',
'mc:Ignorable'
)
foreach ($Attrib in $AttributesToRemove) {
if ( $xaml.Window.GetAttribute($Attrib) ) {
$xaml.Window.RemoveAttribute($Attrib)
}
}
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$syncHash.Window=[Windows.Markup.XamlReader]::Load( $reader )
[xml]$XAML = $xaml
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | %{
#Find all of the form types and add them as members to the synchash
$syncHash.Add($_.Name,$syncHash.Window.FindName($_.Name) )
}
$Script:JobCleanup = [hashtable]::Synchronized(@{})
$Script:Jobs = [system.collections.arraylist]::Synchronized((New-Object System.Collections.ArrayList))
#region Background runspace to clean up jobs
$jobCleanup.Flag = $True
$newRunspace =[runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("jobCleanup",$jobCleanup)
$newRunspace.SessionStateProxy.SetVariable("jobs",$jobs)
$jobCleanup.PowerShell = [PowerShell]::Create().AddScript({
#Routine to handle completed runspaces
Do {
Foreach($runspace in $jobs) {
If ($runspace.Runspace.isCompleted) {
[void]$runspace.powershell.EndInvoke($runspace.Runspace)
$runspace.powershell.dispose()
$runspace.Runspace = $null
$runspace.powershell = $null
}
}
#Clean out unused runspace jobs
$temphash = $jobs.clone()
$temphash | Where {
$_.runspace -eq $Null
} | ForEach {
$jobs.remove($_)
}
Start-Sleep -Seconds 1
} while ($jobCleanup.Flag)
})
$jobCleanup.PowerShell.Runspace = $newRunspace
$jobCleanup.Thread = $jobCleanup.PowerShell.BeginInvoke()
#endregion Background runspace to clean up jobs
$syncHash.button.Add_Click({
#Start-Job -Name Sleeping -ScriptBlock {start-sleep 5}
#while ((Get-Job Sleeping).State -eq 'Running'){
$x+= "."
#region Boe's Additions
$newRunspace =[runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("SyncHash",$SyncHash)
$PowerShell = [PowerShell]::Create().AddScript({
Function write-log{
##----------------------------------------------------------------------------------------------------
## Function: Write-Log
## Purpose: This function writes trace32 log fromat file to user desktop
## Function by: Kaido Järvemets Configuration Manager MVP (http://www.cm12sdk.net)
##----------------------------------------------------------------------------------------------------
PARAM(
[String]$Message,
[int]$severity,
[string]$component
)
$TimeZoneBias = Get-WmiObject -Query "Select Bias from Win32_TimeZone"
$Date= Get-Date -Format "HH:mm:ss.fff"
$Date2= Get-Date -Format "MM-dd-yyyy"
$type=1
"<![LOG[$Message]LOG]!><time=$([char]34)$date+$($TimeZoneBias.bias)$([char]34) date=$([char]34)$date2$([char]34) component=$([char]34)$component$([char]34) context=$([char]34)$([char]34) type=$([char]34)$severity$([char]34) thread=$([char]34)$([char]34) file=$([char]34)$([char]34)>"| Out-File -FilePath "C:\windows\MAJPolicies_SCCM.Log" -Append -NoClobber -Encoding default
}
#On récupère le nom de la machine via les variables d'environnement
$machine=computer01
write-log -Message "-+-+-+-+-+-+-+-+Debut du script MAJPolicies_SCCM+-+-+-+-+-+-+-+-+" -severity 1 -component "Strategies SCCM"
Function Update-Window {
Param (
$Control,
$Property,
$Value,
[switch]$AppendContent
)
# This is kind of a hack, there may be a better way to do this
If ($Property -eq "Close") {
$syncHash.Window.Dispatcher.invoke([action]{$syncHash.Window.Close()},"Normal")
Return
}
# This updates the control based on the parameters passed to the function
$syncHash.$Control.Dispatcher.Invoke([action]{
# This bit is only really meaningful for the TextBox control, which might be useful for logging progress steps
If ($PSBoundParameters['AppendContent']) {
$syncHash.$Control.AppendText($Value)
} Else {
$syncHash.$Control.$Property = $Value
}
}, "Normal")
}
#Lancement du HeartBeat
$HearBeat = '{00000000-0000-0000-0000-000000000003}'|% {Invoke-WMIMethod -ComputerName $machine -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule $_} -ErrorAction SilentlyContinue
#On lance le Heartbeat, si c'est OK il fera les autres actions sinon il se stoppera
if ($HearBeat)
{
Update-Window -Control heartbeat -Property ForeGround -Value green
start-sleep -Milliseconds 850
#$x += 1..15000000
update-window -Control ProgressBar -Property Value -Value 25
#Le log se trouve dans "C:\Windows\CCM\Logs\InventoryAgent.log"
write-log -Message "Lancement du HeartBeat" -severity 1 -component "Heartbeat"
#update-window -Control TextBox -property text -value $x -AppendContent
Update-Window -Control startordieval -Property ForeGround -Value green
start-sleep -Milliseconds 850
update-window -Control ProgressBar -Property Value -Value 50
#Stratégie ordinateur + cycle d'évaluation
sleep -Milliseconds 500
#Les logs se trouvent dans "C:\Windows\CCM\Logs\PolicyAgent.log" et "C:\Windows\CCM\Logs\PolicyEvaluator.log"
'{00000000-0000-0000-0000-000000000021}','{00000000-0000-0000-0000-000000000022}'|% {Invoke-WMIMethod -ComputerName $machine -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule $_} | Out-Null
write-log -Message "Recuperation de strategie ordinateur et cycle d'evaluation" -severity 1 -component "Strategie ordinateur et cycle eval"
Update-Window -Control cycleEvalLog -Property ForeGround -Value green
start-sleep -Milliseconds 500
update-window -Control ProgressBar -Property Value -Value 75
#MAJ logiciels
sleep -Milliseconds 500
#Le log se trouve dans "C:\Windows\CCM\Logs\UpdatesDeployment.log"
'{00000000-0000-0000-0000-000000000108}'|% {Invoke-WMIMethod -ComputerName $machine -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule $_} | Out-Null
write-log -Message "Cycle d'evaluation des deploiements de mises a jours logiciels" -severity 1 -component "Eval deploiemen maj"
Update-Window -Control cycleevalappli -Property ForeGround -Value green
start-sleep -Milliseconds 200
update-window -Control ProgressBar -Property Value -Value 80
#Lancement policies Déploiement applications
sleep -Milliseconds 500
#Le log se trouve dans "C:\Windows\CCM\Logs\AppIntentEval.log"
'{00000000-0000-0000-0000-000000000121}'|% {Invoke-WMIMethod -ComputerName $machine -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule $_} | Out-Null
write-log -Message "Cycle d'evaluation du deploiement de l'application" -severity 1 -component "Eval deploiemen appli"
Update-Window -Control EndScript -Property ForeGround -Value green
start-sleep -Milliseconds 200
update-window -Control ProgressBar -Property Value -Value 100
}
else
{
write-log -Message "Lancement du HeartBeat négatif" -severity 1 -component "Heartbeat"
write-log -Message "Merci de vérifier le client SCCM" -severity 1 -component "Client SCCM"
Update-Window -Control heartbeat -Property ForeGround -Value red
Update-Window -Control startordieval -Property ForeGround -Value red
Update-Window -Control cycleEvalLog -Property ForeGround -Value red
Update-Window -Control cycleevalappli -Property ForeGround -Value red
Update-Window -Control EndScript -Property ForeGround -Value red
start-sleep -Milliseconds 200
Update-Window -Control ProgressBar -Property Value -Value 100
}
write-log -Message "-+-+-+-+-+-+-+-+Fin du script MAJPolicies_SCCM+-+-+-+-+-+-+-+-+" -severity 1 -component "Strategies SCCM"
})
$PowerShell.Runspace = $newRunspace
[void]$Jobs.Add((
[pscustomobject]@{
PowerShell = $PowerShell
Runspace = $PowerShell.BeginInvoke()
}
))
})
#region Window Close
$syncHash.Window.Add_Closed({
Write-Verbose 'Halt runspace cleanup job processing'
$jobCleanup.Flag = $False
#Stop all runspaces
$jobCleanup.PowerShell.Dispose()
})
#endregion Window Close
#endregion Boe's Additions
#$x.Host.Runspace.Events.GenerateEvent( "TestClicked", $x.test, $null, "test event")
#$syncHash.Window.Activate()
$syncHash.Window.ShowDialog() | Out-Null
$syncHash.Error = $Error
})
$psCmd.Runspace = $newRunspace
$data = $psCmd.BeginInvoke()
答: 暂无答案
上一个:查询远程执行功能失败:连接超时
下一个:X-宏列表与自身的笛卡尔积
评论
$script = { powershell "c:\TEMP\MajPoliciesSCCM.ps1" #or & "c:\TEMP\MajPoliciesSCCM.ps1" = same result test-path "c:\TEMP\MajPoliciesSCCM.ps1" >> "C:\TEMP\TEST_REMOTE.txt" } Invoke-Command -ComputerName $machine -ScriptBlock $script