Multi monitor script

Welcome Forums General PowerShell Q&A Multi monitor script

This topic contains 2 replies, has 3 voices, and was last updated by

 
Keymaster
11 months, 1 week ago.

  • Author
    Posts
  • #95919

    Participant
    Points: 64
    Rank: Member

    Hi, I have copied / pasted / fudged together the script below and now need some advice on the next bit. Basically the script will be launched by a scheduled task created by SCCM to install a firmware upgrade of the users machine. When they click install it calls another ps script that actually does the upgrade. The issue I have is that we have a lot of users with multiple screens and their main screen will not always be the top most left in a pod or their left screen in on the desk. I have thought of generating a blank form that is a mile high by a mile wide to cover all of their screens but it will miss the top left or left screen if this is not the main screen. Also I dont know where to insert the blank form generation in the code below as it is my first play with XAML forms. Any help would be great
    please note I have taken out the below to make it easier to debug 🙂
    WindowState="Maximized"
    WindowStyle="None"

    $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 = @"

    "@

    $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
    Function Update-Display {
    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")
    }

    $DisplayText = "

    This is a TextBlock control
    with multiple lines of text.
    3rd Line
    4th Line"

    Update-Display -control TextDisplay -Property Text -Value $DisplayText

    $syncHash.Install.Add_Click({

    $newRunspace =[runspacefactory]::CreateRunspace()
    $newRunspace.ApartmentState = "STA"
    $newRunspace.ThreadOptions = "ReuseThread"
    $newRunspace.Open()
    $newRunspace.SessionStateProxy.SetVariable("SyncHash",$SyncHash)
    $PowerShell = [PowerShell]::Create().AddScript({

    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")
    }

    start-sleep -Milliseconds 850

    $scripttorun = "some powershell script.ps1"

    update-window -Control Progress -Property Value -Value 25

    start-sleep -Milliseconds 850
    update-window -Control Progress -Property Value -Value 50
    Invoke-Expression $scripttorun

    start-sleep -Milliseconds 500
    update-window -Control Progress -Property Value -Value 75

    start-sleep -Milliseconds 200
    update-window -Control Progress -Property Value -Value 100
    })
    $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

    $syncHash.Window.ShowDialog() | Out-Null
    $syncHash.Error = $Error
    })

    $psCmd.Runspace = $newRunspace
    $data = $psCmd.BeginInvoke()

  • #95930

    Participant
    Points: 14
    Rank: Member

    I responded to your other post. Looks like it is in the review queue for the moderator, but you should be able to see it soon.

  • #95943

    Keymaster
    Points: 94
    Team Member
    Rank: Member

    Just popped it in. Spam queue is acting weird lately.

The topic ‘Multi monitor script’ is closed to new replies.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort