Skip to content

Instantly share code, notes, and snippets.

@daBONDi
Last active August 8, 2023 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daBONDi/3c0466f10bbe8d7caf0ea8a126cdab9e to your computer and use it in GitHub Desktop.
Save daBONDi/3c0466f10bbe8d7caf0ea8a126cdab9e to your computer and use it in GitHub Desktop.
Powershell Script for Login Script on Taskschedule to Force Clone Display Configuration
# 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