Skip to content

Commit 3bc7770

Browse files
authored
Merge pull request #4 from DarkCoderSc/dev
1.0.3 Beta 4
2 parents 16ef456 + ab1de77 commit 3bc7770

6 files changed

Lines changed: 183 additions & 100 deletions

File tree

Assets/multi-screen.png

30.6 KB
Loading
0 Bytes
Binary file not shown.

PowerRemoteDesktop_Server/PowerRemoteDesktop_Server.psm1

Lines changed: 73 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@
5151

5252
Add-Type -Assembly System.Windows.Forms
5353
Add-Type -Assembly System.Drawing
54-
Add-Type -MemberDefinition '[DllImport("gdi32.dll")] public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);' -Name GDI32 -Namespace W;
55-
Add-Type -MemberDefinition '[DllImport("User32.dll")] public static extern int GetDC(IntPtr hWnd);[DllImport("User32.dll")] public static extern int ReleaseDC(IntPtr hwnd, int hdc);[DllImport("User32.dll")] public static extern bool SetProcessDPIAware();' -Name User32 -Namespace W;
54+
Add-Type -MemberDefinition '[DllImport("User32.dll")] public static extern bool SetProcessDPIAware();' -Name User32 -Namespace W;
5655

57-
$global:PowerRemoteDesktopVersion = "1.0.beta.3"
56+
$global:PowerRemoteDesktopVersion = "1.0.3.beta.4"
5857

5958
enum TransportMode {
6059
Raw = 1
@@ -97,7 +96,7 @@ function Test-PasswordComplexity
9796
.DESCRIPTION
9897
To return True, Password must follow bellow complexity rules:
9998
* Minimum 12 Characters.
100-
* One of following symbols: "!@#$%^&*_".
99+
* One of following symbols: "!@#%^&*_".
101100
* At least of lower case character.
102101
* At least of upper case character.
103102
@@ -109,7 +108,7 @@ function Test-PasswordComplexity
109108
[string] $PasswordCandidate
110109
)
111110

112-
$complexityRules = "(?=^.{12,}$)(?=.*[!@#$%^&*_]+)(?=.*[a-z])(?=.*[A-Z]).*$"
111+
$complexityRules = "(?=^.{12,}$)(?=.*[!@#%^&*_]+)(?=.*[a-z])(?=.*[A-Z]).*$"
113112

114113
return ($PasswordCandidate -match $complexityRules)
115114
}
@@ -501,24 +500,6 @@ function Resolve-AuthenticationChallenge
501500
return $solution
502501
}
503502

504-
function Get-ResolutionScaleFactor
505-
{
506-
<#
507-
.SYNOPSIS
508-
Return current screen scale factor
509-
#>
510-
511-
$hdc = [W.User32]::GetDC(0)
512-
try
513-
{
514-
return [W.GDI32]::GetDeviceCaps($hdc, 117) / [W.GDI32]::GetDeviceCaps($hdc, 10)
515-
}
516-
finally
517-
{
518-
[W.User32]::ReleaseDC(0, $hdc) | Out-Null
519-
}
520-
}
521-
522503
function Get-LocalMachineInformation
523504
{
524505
<#
@@ -531,30 +512,42 @@ function Get-LocalMachineInformation
531512
532513
This function is expected to be progressively updated with new required session information.
533514
#>
534-
$screenBounds = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
515+
516+
$screens = @()
517+
518+
$i = 0
519+
foreach ($screen in ([System.Windows.Forms.Screen]::AllScreens | Sort-Object -Property Primary -Descending))
520+
{
521+
$i++
522+
523+
$screens += New-Object -TypeName PSCustomObject -Property @{
524+
Id = $i
525+
Name = $screen.DeviceName
526+
Primary = $screen.Primary
527+
Width = $screen.Bounds.Width
528+
Height = $screen.Bounds.Height
529+
X = $screen.Bounds.X
530+
Y = $screen.Bounds.Y
531+
}
532+
}
535533

536534
return New-Object PSCustomObject -Property @{
537535
MachineName = [Environment]::MachineName
538536
Username = [Environment]::UserName
539537
WindowsVersion = [Environment]::OSVersion.VersionString
540-
541-
ScreenInformation = New-Object -TypeName PSCustomObject -Property @{
542-
Width = $screenBounds.Width
543-
Height = $screenBounds.Height
544-
X = $screenBounds.X
545-
Y = $screenBounds.Y
546-
}
538+
Screens = ($screens)
547539
}
548540
}
549541

550542
class ServerSession {
551543
<#
552544
.SYNOPSIS
553545
PowerRemoteDesktop Session Class.
554-
#>
546+
#>
555547

556548
[string] $Id = ""
557549
[string] $TiedAddress = ""
550+
[string] $Screen = ""
558551

559552
ServerSession([string] $RemoteAddress) {
560553
<#
@@ -567,11 +560,10 @@ class ServerSession {
567560
#>
568561

569562
$this.Id = (SHA512FromString -String (-join ((33..126) | Get-Random -Count 128 | ForEach-Object{[char] $_})))
570-
$this.TiedAddress = $RemoteAddress
563+
$this.TiedAddress = $RemoteAddress
571564
}
572565

573-
[bool] CompareWith([string] $Id, [string] $RemoteAddress)
574-
{
566+
[bool] CompareWith([string] $Id, [string] $RemoteAddress) {
575567
return ($this.Id -eq $Id) -and ($this.TiedAddress -eq $RemoteAddress)
576568
}
577569
}
@@ -777,6 +769,15 @@ class ClientIO {
777769

778770
$this.Writer.WriteLine(($sessionInformation | ConvertTo-Json -Compress))
779771

772+
if ($sessionInformation.Screens.Length -gt 1)
773+
{
774+
Write-Verbose "Current system have $($sessionInformation.Screens.Length) Screens. Waiting for Remote Viewer to choose which screen to capture."
775+
776+
$screenName = $this.Reader.ReadLine()
777+
778+
$session.Screen = $screenName
779+
}
780+
780781
Write-Verbose "Handshake done."
781782

782783
return $session
@@ -1043,24 +1044,28 @@ $global:DesktopStreamScriptBlock = {
10431044
.SYNOPSIS
10441045
Return a snapshot of primary screen desktop.
10451046
1046-
.DESCRIPTION
1047-
Notice:
1048-
At this time, PowerRemoteDesktop only supports PrimaryScreen.
1049-
Even if multi-screen capture is a very easy feature to implement, It will probably be present
1050-
in final version 1.0
1047+
.PARAMETER Screen
1048+
Define target screen to capture (if multiple monitor exists).
1049+
Default is primary screen
10511050
#>
1051+
param (
1052+
[System.Windows.Forms.Screen] $Screen = $null
1053+
)
10521054
try
10531055
{
1054-
$primaryDesktop = [System.Windows.Forms.Screen]::PrimaryScreen
1056+
if (-not $Screen)
1057+
{
1058+
$Screen = [System.Windows.Forms.Screen]::PrimaryScreen
1059+
}
10551060

10561061
$size = New-Object System.Drawing.Size(
1057-
$primaryDesktop.Bounds.Size.Width,
1058-
$primaryDesktop.Bounds.Size.Height
1062+
$Screen.Bounds.Size.Width,
1063+
$Screen.Bounds.Size.Height
10591064
)
10601065

10611066
$location = New-Object System.Drawing.Point(
1062-
$primaryDesktop.Bounds.Location.X,
1063-
$primaryDesktop.Bounds.Location.Y
1067+
$Screen.Bounds.Location.X,
1068+
$Screen.Bounds.Location.Y
10641069
)
10651070

10661071
$bitmap = New-Object System.Drawing.Bitmap($size.Width, $size.Height)
@@ -1087,6 +1092,10 @@ $global:DesktopStreamScriptBlock = {
10871092
}
10881093

10891094
$imageQuality = 100
1095+
if ($syncHash.Param.ImageQuality -ge 0 -and $syncHash.Param.ImageQuality -lt 100)
1096+
{
1097+
$imageQuality = $syncHash.Param.ImageQuality
1098+
}
10901099
try
10911100
{
10921101
[System.IO.MemoryStream] $oldImageStream = New-Object System.IO.MemoryStream
@@ -1102,7 +1111,7 @@ $global:DesktopStreamScriptBlock = {
11021111
{
11031112
try
11041113
{
1105-
$desktopImage = Get-DesktopImage
1114+
$desktopImage = Get-DesktopImage -Screen $syncHash.Param.Screen
11061115

11071116
$imageStream = New-Object System.IO.MemoryStream
11081117

@@ -1509,6 +1518,11 @@ function Invoke-RemoteDesktopServer
15091518
15101519
.PARAMETER DisableVerbosity
15111520
Disable verbosity (not recommended)
1521+
1522+
.PARAMETER ImageQuality
1523+
JPEG Compression level from 0 to 100
1524+
0 = Lowest quality.
1525+
100 = Highest quality.
15121526
#>
15131527

15141528
param (
@@ -1523,7 +1537,9 @@ function Invoke-RemoteDesktopServer
15231537
[TransportMode] $TransportMode = "Raw",
15241538
[switch] $TLSv1_3,
15251539

1526-
[switch] $DisableVerbosity
1540+
[switch] $DisableVerbosity,
1541+
1542+
[int] $ImageQuality = 100
15271543
)
15281544

15291545

@@ -1546,10 +1562,7 @@ function Invoke-RemoteDesktopServer
15461562

15471563
Write-Banner
15481564

1549-
if (Get-ResolutionScaleFactor -ne 1)
1550-
{
1551-
[W.User32]::SetProcessDPIAware()
1552-
}
1565+
[W.User32]::SetProcessDPIAware() | Out-Null
15531566

15541567
if (-not (Test-Administrator) -and -not $CertificateFile -and -not $EncodedCertificate)
15551568
{
@@ -1572,8 +1585,8 @@ function Invoke-RemoteDesktopServer
15721585
if (-not $Password)
15731586
{
15741587
$Password = (
1575-
# a-Z, 0-9, !@#$%^&*_
1576-
-join ((48..57) + (64..90) + (35..38) + 33 + 42 + 94 + 95 + (97..122) | Get-Random -Count 18 | ForEach-Object{[char] $_})
1588+
# a-Z, 0-9, !@#%^&*_
1589+
-join ((48..57) + (64..90) + 35 + (37..38) + 33 + 42 + 94 + 95 + (97..122) | Get-Random -Count 18 | ForEach-Object{[char] $_})
15771590
)
15781591

15791592
Write-Host -NoNewLine "Server password: """
@@ -1586,7 +1599,7 @@ function Invoke-RemoteDesktopServer
15861599
{
15871600
throw "Password complexity is too weak. Please choose a password following following rules:`r`n`
15881601
* Minimum 12 Characters`r`n`
1589-
* One of following symbols: ""!@#$%^&*_""`r`n`
1602+
* One of following symbols: ""!@#%^&*_""`r`n`
15901603
* At least of lower case character`r`n`
15911604
* At least of upper case character`r`n"
15921605
}
@@ -1635,11 +1648,16 @@ function Invoke-RemoteDesktopServer
16351648
# Remote Viewer will then need to establish a new session from scratch.
16361649
$clientControl = $server.PullClient(10 * 1000);
16371650

1651+
# Grab desired screen to capture
1652+
$screen = [System.Windows.Forms.Screen]::AllScreens | Where-Object -FilterScript { $_.DeviceName -eq $server.Session.Screen }
1653+
16381654
# Create Runspace #1 for Desktop Streaming.
16391655
$param = New-Object -TypeName PSCustomObject -Property @{
16401656
Client = $clientDesktop
1657+
Screen = $screen
1658+
ImageQuality = $ImageQuality
16411659
}
1642-
1660+
16431661
$newRunspace = (New-RunSpace -ScriptBlock $global:DesktopStreamScriptBlock -Param $param)
16441662
$runspaces.Add($newRunspace)
16451663

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)