Thanks for MonitorConfig — I've been using it as a base for some 2-PC monitor sharing scripting and noticed that VCP 0x60 (Input Select) is documented in VCPFeatures.csv and reachable via Set-MonitorVCPValue, but doesn't have a typed wrapper the way Brightness / Contrast / Color do. Wanted to gauge interest in contributing one before writing a PR — this would be the first external contribution to MonitorConfig, so happy to align on shape (or defer entirely) before investing the work.
Use case
Multi-input displays where a script wants to flip between HDMI / DP / USB-C without going through the OSD. Two common patterns:
- KVM-style switching: two PCs each connected via a different input; a script on PC A flips both displays over to the input PC B is using.
- Dock toggle: workstation runs internal HDMI for one task, eGPU on DP for another.
Today this works fine via:
$mon | Set-MonitorVCPValue -VCPCode 0x60 -Value 17
…but the values are MCCS-defined constants and could be exposed as a typed surface, the way Brightness already is.
Proposed shape
# Named (MCCS-standard) values
$mon | Set-MonitorInput -Source HDMI1
$mon | Set-MonitorInput -Source DisplayPort1
# Raw value for vendor-specific inputs (e.g. Dell USB-C = 0x1B)
$mon | Set-MonitorInput -Value 0x1B
# Read current input + capability
$mon | Get-MonitorInput
# Monitor CurrentSource CurrentValue PossibleValues
# \\.\DISPLAY1 HDMI1 17 15 (DisplayPort1), 17 (HDMI1), 27 (Custom)
Source would accept names mirroring the MCCS section "Input Select / VCP code 0x60":
Vga1 = 0x01, Vga2 = 0x02
Dvi1 = 0x03, Dvi2 = 0x04
DisplayPort1 = 0x0F, DisplayPort2 = 0x10
Hdmi1 = 0x11, Hdmi2 = 0x12
... etc.
Tab-completion would be monitor-aware: when -Monitor is bound, suggestions are filtered to the values that monitor advertises in its DDC/CI capability string. On a P2725QE that reports 60(0F 11 1B), -Source <TAB> would show just DisplayPort1 and Hdmi1, and -Value <TAB> would also surface the vendor-specific 0x1B (USB-C, not in the MCCS list) with a description. Falls back to the full MCCS list when no monitor is bound or its capability string can't be read.
Implementation notes
Fits the existing pattern of typed wrapper over Set-MonitorVCPValue:
- Add
KnownVcpCodes.InputSelect = 0x60
- New
MonitorInputSource enum under API/
- Add
VCPMonitor.GetInputSource() / SetInputSource(uint) next to the existing GetBrightnessLevel / SetBrightnessLevel etc.
- New
GetMonitorInputCommand.cs / SetMonitorInputCommand.cs mirroring SetMonitorBrightnessCommand (Monitor pipeline arg at position 0, single Source / Value param at position 1, parameter sets to choose named vs raw)
- New
MonitorInputCompleter.cs with IArgumentCompleter classes for -Source and -Value, sharing one resolver that turns the bound -Monitor value (object or device-name string) into a VCPMonitor and reads VCP 0x60 valid values from ParsedCapabilityString
WMIMonitor doesn't apply (internal panels can't change input), so this would be VCP-only and error gracefully on WMIMonitor like WMIOptionsSetOnVCPDisplay does today
One small documentation nuance worth flagging: some monitors report a different EDID Product Code per active input (e.g. Dell P2725QE shows DELF168 over HDMI but DELF169 over DP — same physical panel). Doesn't affect this cmdlet, but it can surprise users who try to identify monitors by InstanceName across hosts. A README note seems sufficient.
Questions
Are PRs along these lines welcome? If yes, three design choices I'd like your opinion on:
-
Naming: stick to MCCS spec literal (Hdmi1, Vga1, DisplayPort1) for fidelity, or use friendlier forms (HDMI, VGA, DP) with 1/2 suffixes only when needed?
-
-Source parameter type — string vs enum. This one has a real tradeoff and I'd like your call before I send a PR:
I started with MonitorInputSource as a public enum and -Source typed to it. PowerShell's binder, however, uses its own enum-name completion for enum-typed parameters and bypasses both [ArgumentCompleter] and Register-ArgumentCompleter for them — verified on PS 7 with a sentinel scriptblock that was silently dropped. To get the monitor-aware completion described above I switched -Source to String and parse it to the enum at ProcessRecord time, with an ArgumentException that lists the accepted MCCS names if the input isn't recognized. The enum type is still public (used by the -Value completer for friendly names and would be referenced by Get-MonitorInput output below).
That trades binding-time type safety for monitor-aware tab-completion. I'd lean toward String because the completion is the main UX win for this cmdlet, but the tradeoff is real — happy to revert to the enum if you'd rather keep -Source strict and let -Value carry the monitor-aware completion alone.
-
Get-MonitorInput shape: include PossibleValues in the default output (more useful for discovery), or keep symmetrical with Get-MonitorBrightness and return just the current state? (Current sketch in MonitorInputInfo is CurrentValue + CurrentSource?, the latter null for vendor-specific values.)
Happy to draft a PR on whichever shape you prefer, or to leave it for you if you'd rather own the addition.
Thanks for
MonitorConfig— I've been using it as a base for some 2-PC monitor sharing scripting and noticed that VCP0x60(Input Select) is documented inVCPFeatures.csvand reachable viaSet-MonitorVCPValue, but doesn't have a typed wrapper the way Brightness / Contrast / Color do. Wanted to gauge interest in contributing one before writing a PR — this would be the first external contribution to MonitorConfig, so happy to align on shape (or defer entirely) before investing the work.Use case
Multi-input displays where a script wants to flip between HDMI / DP / USB-C without going through the OSD. Two common patterns:
Today this works fine via:
…but the values are MCCS-defined constants and could be exposed as a typed surface, the way Brightness already is.
Proposed shape
Sourcewould accept names mirroring the MCCS section "Input Select / VCP code 0x60":Tab-completion would be monitor-aware: when
-Monitoris bound, suggestions are filtered to the values that monitor advertises in its DDC/CI capability string. On a P2725QE that reports60(0F 11 1B),-Source <TAB>would show justDisplayPort1andHdmi1, and-Value <TAB>would also surface the vendor-specific0x1B(USB-C, not in the MCCS list) with a description. Falls back to the full MCCS list when no monitor is bound or its capability string can't be read.Implementation notes
Fits the existing pattern of typed wrapper over
Set-MonitorVCPValue:KnownVcpCodes.InputSelect = 0x60MonitorInputSourceenum underAPI/VCPMonitor.GetInputSource()/SetInputSource(uint)next to the existingGetBrightnessLevel/SetBrightnessLeveletc.GetMonitorInputCommand.cs/SetMonitorInputCommand.csmirroringSetMonitorBrightnessCommand(Monitor pipeline arg at position 0, singleSource/Valueparam at position 1, parameter sets to choose named vs raw)MonitorInputCompleter.cswithIArgumentCompleterclasses for-Sourceand-Value, sharing one resolver that turns the bound-Monitorvalue (object or device-name string) into aVCPMonitorand reads VCP 0x60 valid values fromParsedCapabilityStringWMIMonitordoesn't apply (internal panels can't change input), so this would be VCP-only and error gracefully onWMIMonitorlikeWMIOptionsSetOnVCPDisplaydoes todayOne small documentation nuance worth flagging: some monitors report a different EDID Product Code per active input (e.g. Dell P2725QE shows
DELF168over HDMI butDELF169over DP — same physical panel). Doesn't affect this cmdlet, but it can surprise users who try to identify monitors byInstanceNameacross hosts. A README note seems sufficient.Questions
Are PRs along these lines welcome? If yes, three design choices I'd like your opinion on:
Naming: stick to MCCS spec literal (
Hdmi1,Vga1,DisplayPort1) for fidelity, or use friendlier forms (HDMI,VGA,DP) with1/2suffixes only when needed?-Sourceparameter type — string vs enum. This one has a real tradeoff and I'd like your call before I send a PR:I started with
MonitorInputSourceas a public enum and-Sourcetyped to it. PowerShell's binder, however, uses its own enum-name completion for enum-typed parameters and bypasses both[ArgumentCompleter]andRegister-ArgumentCompleterfor them — verified on PS 7 with a sentinel scriptblock that was silently dropped. To get the monitor-aware completion described above I switched-SourcetoStringand parse it to the enum atProcessRecordtime, with anArgumentExceptionthat lists the accepted MCCS names if the input isn't recognized. The enum type is still public (used by the-Valuecompleter for friendly names and would be referenced byGet-MonitorInputoutput below).That trades binding-time type safety for monitor-aware tab-completion. I'd lean toward
Stringbecause the completion is the main UX win for this cmdlet, but the tradeoff is real — happy to revert to the enum if you'd rather keep-Sourcestrict and let-Valuecarry the monitor-aware completion alone.Get-MonitorInputshape: includePossibleValuesin the default output (more useful for discovery), or keep symmetrical withGet-MonitorBrightnessand return just the current state? (Current sketch inMonitorInputInfoisCurrentValue+CurrentSource?, the latter null for vendor-specific values.)Happy to draft a PR on whichever shape you prefer, or to leave it for you if you'd rather own the addition.