Last active
August 8, 2023 13:54
-
-
Save daBONDi/3c0466f10bbe8d7caf0ea8a126cdab9e to your computer and use it in GitHub Desktop.
Powershell Script for Login Script on Taskschedule to Force Clone Display Configuration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# clone-display.ps1 | |
# | |
# Test with CIM if there are Multiple Montiors Connected and | |
# try for 60 seconds to Switch Display to Clone/Presentation Mode | |
# | |
# Set WriteDebugLogEnabled to $true if for some diagnostic logging | |
# Register Schedule Task | |
# $Trigger= New-ScheduledTaskTrigger -AtLogon | |
# $TaskPrincipal = New-ScheduledTaskPrincipal -GroupId $((Get-LocalGroup -SID "S-1-5-32-545").name) | |
# $Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy ByPass -NoProfile -NonInteractive -NoLogo -WindowStyle hidden -File ""PATH TO SCRIPT FILE""" | |
# $IEC = Register-ScheduledTask -TaskName "Clone-Displays" -Trigger $Trigger -Principal $TaskPrincipal -Action $Action -Force | |
# Ammount of Trys with 1 Second wait before Exit | |
$TimeOutInSeconds = 60; | |
# Debugging Setup | |
$WriteDebugLogEnabled = $false; | |
$DebugLogPath = "c:\Users\Public\FJ-CloneDisplay.log"; | |
Add-Type -TypeDefinition @" | |
using System; | |
using System.Runtime.InteropServices; | |
public static class User32 | |
{ | |
[Flags] | |
public enum SetDisplayConfigFlags : uint | |
{ | |
SDC_TOPOLOGY_INTERNAL = 0x00000001, | |
SDC_TOPOLOGY_CLONE = 0x00000002, | |
SDC_TOPOLOGY_EXTEND = 0x00000004, | |
SDC_TOPOLOGY_EXTERNAL = 0x00000008, | |
SDC_APPLY = 0x00000080 | |
} | |
[Flags] | |
public enum QueryDisplayConfigFlags: uint | |
{ | |
QDC_ALL_PATHS = 0x00000001, | |
QDC_ONLY_ACTIVE_PATHS = 0x00000002, | |
QDC_DATABASE_CURRENT = 0x00000004 | |
} | |
[DllImport("user32.dll", CharSet = CharSet.Unicode)] | |
private static extern long SetDisplayConfig(uint numPathArrayElements, | |
IntPtr pathArray, uint numModeArrayElements, IntPtr modeArray, SetDisplayConfigFlags flags); | |
public static long CloneDisplays() { | |
return SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, SetDisplayConfigFlags.SDC_TOPOLOGY_CLONE | SetDisplayConfigFlags.SDC_APPLY); | |
} | |
public static long ExtendDisplays() { | |
return SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, SetDisplayConfigFlags.SDC_TOPOLOGY_EXTEND | SetDisplayConfigFlags.SDC_APPLY); | |
} | |
public static long ExternalDisplay() { | |
return SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, SetDisplayConfigFlags.SDC_TOPOLOGY_EXTERNAL | SetDisplayConfigFlags.SDC_APPLY); | |
} | |
public static long InternalDisplay() { | |
return SetDisplayConfig(0, IntPtr.Zero, 0, IntPtr.Zero, SetDisplayConfigFlags.SDC_TOPOLOGY_INTERNAL | SetDisplayConfigFlags.SDC_APPLY); | |
} | |
} | |
"@ | |
# Handling Logging Debug Messages | |
function log($Message){ | |
if($WriteDebugLogEnabled){ | |
Add-Content -Path $DebugLogPath -Value "$(Get-Date) - $Message" | |
} | |
} | |
# Test for Dual Monitor Setup | |
$MonitorCount = (Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams | Measure-Object).Count | |
if($MonitorCount -ge 2){ | |
log("Monitor Count Found: $MonitorCount") | |
# Returns Long Value 5 on when Desktop is not fully loaded | |
for($i=1;$i -le $TimeOutInSeconds;$i++){ | |
[long] $result = [User32]::CloneDisplays() | |
# $result Value 5 on when Desktop is not fully loaded | |
if($result -eq 0){ | |
log("Switched to Clone Mode") | |
break; | |
}else{ | |
if($result -eq 5){ | |
log("Desktop not fully loaded: $result") | |
}else{ | |
log("Switch To Clone failed with error: $result") | |
} | |
}; | |
Start-Sleep -Seconds 1; | |
} | |
}else{ | |
log("Did not find Multiple Monitors - Cim Montior Count Value: $MonitorCount") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment