Command line output:
C:\powercfg -availablesleepstates
The following sleep states are available on this system:
Standby (S3)
Hibernate
Hybrid Sleep
Fast Startup
The following sleep states are not available on this system:
Standby (S1)
The system firmware does not support this standby state.
Standby (S2)
The system firmware does not support this standby state.
Standby (S0 Low Power Idle)
The system firmware does not support this standby state.
powershell script:
$info = (powercfg /a | Select-String -Pattern "sleep states are available" -context 4) | select -Last 4
$items = $info -split ","
$ourObject = New-Object -TypeName psobject
$ourObject | Add-Member -MemberType NoteProperty -Name PCFG0bj -Value $items -Force
$ourObject | fl
Output:
PCFG0bj : {> The following sleep states are available on this system:
Standby (S3)
Hibernate
Hybrid Sleep
Fast Startup}
Here is a PowerShell function that exposes SYSTEM_POWER_CAPABILITIES directly, as #Persistent13 suggested. The struct has been updated to include new variables, such as AoAc to show if Modern Standby (S0) is supported. An updated definition for SYSTEM_POWER_CAPABILITIES was more difficult to find than I thought, as the Microsoft KB incorrectly displays SYSTEM_BATTERY_STATE. I managed to find some alternative resources, which are linked in the TypeDef.
Function:
Function Get-PowerCapabilities
{
Add-Type -TypeDefinition #"
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public static class PowerCfg
{
[DllImport("PowrProf.dll")]
public static extern bool GetPwrCapabilities(out SYSTEM_POWER_CAPABILITIES lpSystemPowerCapabilities);
public static SYSTEM_POWER_CAPABILITIES GetCapabilities()
{
SYSTEM_POWER_CAPABILITIES spc;
bool well = GetPwrCapabilities(out spc);
return spc;
}
// https://github.com/MicrosoftDocs/sdk-api/blob/docs/sdk-api-src/content/winnt/ns-winnt-system_power_capabilities.md
// https://www.pinvoke.net/default.aspx/Structures/SYSTEM_POWER_CAPABILITIES.html
[Serializable]
public struct SYSTEM_POWER_CAPABILITIES
{
[MarshalAs(UnmanagedType.I1)]
public bool PowerButtonPresent; //If this member is TRUE, there is a system power button.
[MarshalAs(UnmanagedType.I1)]
public bool SleepButtonPresent; //If this member is TRUE, there is a system sleep button.
[MarshalAs(UnmanagedType.I1)]
public bool LidPresent; //If this member is TRUE, there is a lid switch.
[MarshalAs(UnmanagedType.I1)]
public bool SystemS1; //If this member is TRUE, the operating system supports sleep state S1.
[MarshalAs(UnmanagedType.I1)]
public bool SystemS2; //If this member is TRUE, the operating system supports sleep state S2.
[MarshalAs(UnmanagedType.I1)]
public bool SystemS3; //If this member is TRUE, the operating system supports sleep state S3.
[MarshalAs(UnmanagedType.I1)]
public bool SystemS4; //If this member is TRUE, the operating system supports sleep state S4 (hibernation).
[MarshalAs(UnmanagedType.I1)]
public bool SystemS5; //If this member is TRUE, the operating system supports power off state S5 (soft off).
[MarshalAs(UnmanagedType.I1)]
public bool HiberFilePresent; //If this member is TRUE, the system hibernation file is present.
[MarshalAs(UnmanagedType.I1)]
public bool FullWake; //If this member is TRUE, the system supports wake capabilities.
[MarshalAs(UnmanagedType.I1)]
public bool VideoDimPresent; //If this member is TRUE, the system supports video display dimming capabilities.
[MarshalAs(UnmanagedType.I1)]
public bool ApmPresent; //If this member is TRUE, the system supports APM BIOS power management features.
[MarshalAs(UnmanagedType.I1)]
public bool UpsPresent; //If this member is TRUE, there is an uninterruptible power supply (UPS).
[MarshalAs(UnmanagedType.I1)]
public bool ThermalControl; //If this member is TRUE, the system supports thermal zones.
[MarshalAs(UnmanagedType.I1)]
public bool ProcessorThrottle; //If this member is TRUE, the system supports processor throttling.
public byte ProcessorMinThrottle; //The minimum level of system processor throttling supported, expressed as a percentage.
public byte ProcessorMaxThrottle; //The maximum level of system processor throttling supported, expressed as a percentage. Also known as ProcessorThrottleScale before Windows XP
[MarshalAs(UnmanagedType.I1)]
public bool FastSystemS4; //If this member is TRUE, the system supports the hybrid sleep state.
[MarshalAs(UnmanagedType.I1)]
public bool Hiberboot; //If this member is set to TRUE, the system is currently capable of performing a fast startup transition. This setting is based on whether the machine is capable of hibernate, whether the machine currently has hibernate enabled (hiberfile exists), and the local and group policy settings for using hibernate (including the Hibernate option in the Power control panel).
[MarshalAs(UnmanagedType.I1)]
public bool WakeAlarmPresent; //If this member is TRUE, the platform has support for ACPI wake alarm devices.
[MarshalAs(UnmanagedType.I1)]
public bool AoAc; //If this member is TRUE, the system supports the S0 low power idle model.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] spare2; //Unknown
[MarshalAs(UnmanagedType.I1)]
public bool DiskSpinDown; //If this member is TRUE, the system supports allowing the removal of power to fixed disk devices.
public byte HiberFileType; //Unknown
[MarshalAs(UnmanagedType.I1)]
public bool AoAcConnectivitySupported; //Unknown
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] spare3; //Reserved
[MarshalAs(UnmanagedType.I1)]
public bool SystemBatteriesPresent; //If this member is TRUE, there are one or more batteries in the system.
[MarshalAs(UnmanagedType.I1)]
public bool BatteriesAreShortTerm; //If this member is TRUE, the system batteries are short-term. Short-term batteries are used in uninterruptible power supplies (UPS).
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public BATTERY_REPORTING_SCALE[] BatteryScale; //A BATTERY_REPORTING_SCALE structure that contains information about how system battery metrics are reported.
public SYSTEM_POWER_STATE AcOnLineWake; //The lowest system sleep state (Sx) that will generate a wake event when the system is on AC power.
public SYSTEM_POWER_STATE SoftLidWake; //The lowest system sleep state (Sx) that will generate a wake event via the lid switch.
public SYSTEM_POWER_STATE RtcWake; //The lowest system sleep state (Sx) supported by hardware that will generate a wake event via the Real Time Clock (RTC).
public SYSTEM_POWER_STATE MinDeviceWakeState; //The minimum allowable system power state supporting wake events. Note that this state may change as different device drivers are installed on the system.
public SYSTEM_POWER_STATE DefaultLowLatencyWake; //The default system power state used if an application calls RequestWakeupLatency with LT_LOWEST_LATENCY.
}
// https://github.com/MicrosoftDocs/sdk-api/blob/docs/sdk-api-src/content/winnt/ns-winnt-battery_reporting_scale.md
public struct BATTERY_REPORTING_SCALE
{
public UInt32 Granularity;
public UInt32 Capacity;
}
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-system_power_state
public enum SYSTEM_POWER_STATE
{
PowerSystemUnspecified = 0, //Unspecified system power state.
PowerSystemWorking = 1, //Specifies system power state S0.
PowerSystemSleeping1 = 2, //Specifies system power state S1.
PowerSystemSleeping2 = 3, //Specifies system power state S2.
PowerSystemSleeping3 = 4, //Specifies system power state S3.
PowerSystemHibernate = 5, //Specifies system power state S4 (HIBERNATE).
PowerSystemShutdown = 6, //Specifies system power state S5 (OFF).
PowerSystemMaximum = 7 //Specifies the maximum enumeration value.
}
}
"#
[PowerCfg]::GetCapabilities()
}
Usage:
PS C:\WINDOWS\system32> Get-PowerCapabilities
PowerButtonPresent : True
SleepButtonPresent : True
LidPresent : True
SystemS1 : False
SystemS2 : False
SystemS3 : True
SystemS4 : True
SystemS5 : True
HiberFilePresent : True
FullWake : True
VideoDimPresent : True
ApmPresent : False
UpsPresent : False
ThermalControl : True
ProcessorThrottle : False
ProcessorMinThrottle : 0
ProcessorMaxThrottle : 0
FastSystemS4 : True
Hiberboot : True
WakeAlarmPresent : False
AoAc : False
spare2 : {0, 2, 0}
DiskSpinDown : False
HiberFileType : 0
AoAcConnectivitySupported : False
spare3 : {0, 0, 0, 1...}
SystemBatteriesPresent : False
BatteriesAreShortTerm : False
BatteryScale : {PowerCfg7+BATTERY_REPORTING_SCALE, PowerCfg7+BATTERY_REPORTING_SCALE,
PowerCfg7+BATTERY_REPORTING_SCALE}
AcOnLineWake : PowerSystemHibernate
SoftLidWake : PowerSystemUnspecified
RtcWake : PowerSystemUnspecified
MinDeviceWakeState : PowerSystemUnspecified
DefaultLowLatencyWake : PowerSystemUnspecified
I'm not sure BatteryScale is accurate, as it returns all 0s for me. All the PowerSystemUnspecified values are a bit concerning too. But the S0-5 sleep states all seem to report correctly.
Related
How can I set a none data type.[Microsoft.Win32.RegistryValueKind]::None in Powershell 2.0?
Powershell 2.0 has types "Unknown, String, ExpandString, Binary, DWord, MultiString, QWord".
learn.microsoft.com
Add-Type -TypeDefinition #"
using System.Runtime.InteropServices;
using System.Security.Principal;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
namespace AdvapiSolution
{
public class Advapi
{
public enum HKEY : uint
{
HKEY_CLASSES_ROOT = 0x80000000,
HKEY_CURRENT_USER = 0x80000001,
HKEY_LOCAL_MACHINE = 0x80000002,
HKEY_USERS = 0x80000003,
HKEY_PERFORMANCE_DATA = 0x80000004,
HKEY_PERFORMANCE_TEXT = 0x80000050,
HKEY_PERFORMANCE_NLSTEXT = 0x80000060,
HKEY_CURRENT_CONFIG = 0x80000005
}
private enum VALUE_TYPE : uint
{
REG_NONE= 0,
REG_SZ = 1,
REG_EXPAND_SZ = 2,
REG_BINARY = 3,
REG_DWORD = 4,
REG_DWORD_LITTLE_ENDIAN = 4,
REG_DWORD_BIG_ENDIAN = 5,
REG_LINK = 6,
REG_MULTI_SZ = 7,
REG_RESOURCE_LIST = 8,
REG_FULL_RESOURCE_DESCRIPTOR = 9,
REG_RESOURCE_REQUIREMENTS_LIST = 10,
REG_QWORD_LITTLE_ENDIAN = 11
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto, BestFitMapping = false)]
private static extern int RegSetKeyValueW (
HKEY hkey,
string lpSubKey,
string lpValueName,
VALUE_TYPE type,
byte[] data,
uint dataLength);
public int set_key(HKEY hkey, string subkey, string valuename){
return RegSetKeyValueW(hkey, subkey, valuename, VALUE_TYPE.REG_NONE, null, 0);
}
}
}
"#
In my case data equals null and type is REG_NONE. You can change set_key as you like with object:
$Advapiobject = New-Object 'AdvapiSolution.Advapi'
$Advapiobject.set_key('HKEY_CURRENT_USER',$yoursubkey, $yourvaluename, 'REG_NONE')
Another way is using a static method set_key.
Change set_key to public static int set_key:
[AdvapiSolution.Advapi]::set_key('HKEY_CURRENT_USER',$yoursubkey, $yourvaluename, 'REG_NONE').
If it returns 0, it's okay. If the function fails, the return value is a nonzero error code defined in Winerror.h.
System Error Codes
(As implied in your question), [Microsoft.Win32.RegistryValueKind]::None (which translates to a REG_NONE registry value) requires at least .NET Framework 4, whereas Windows PowerShell v2 is built on .NET Framework 2. (Only Windows PowerShell v3 and above are built on .NET Framework 4 and above).
Unlike C#, PowerShell does not allow you to pass the numerical value of an enum-typed parameter if that value doesn't represent an officially defined member of that enumeration (at that time, in the underlying framework), so attempting to pass (-1), the value of [Microsoft.Win32.RegistryValueKind]::None, does not work in Windows PowerShell v2 - neither with New-ItemProperty / Set-ItemProperty's -Type parameter, nor with .NET API calls ([Microsoft.Win32.Registry]::SetValue(...)).
Therefore, in Windows PowerShell v2, calling the Windows API via P/Invoke declarations implemented via Add-Type is probably your only option - see the RegSetKeyValue() WinAPI function (among others).
Building on your own helpful answer, here's a streamlined solution, which:
uses Add-Type's -MemberDefinition parameter to simplify creation of types that wrap P/Invoke calls.
Exposes a static [WinApiHelper.Registry]::SetNoneValue() method, which:
focuses only on creating REG_NONE values
also supports creating such values with byte data ([byte[]] arrays)
has no return value, but throws a Win32Exception should an error occur.
Add-Type -Namespace WinApiHelper -Name Registry -MemberDefinition #'
public enum HKEY : uint
{
HKEY_CLASSES_ROOT = 0x80000000,
HKEY_CURRENT_CONFIG = 0x80000005,
HKEY_CURRENT_USER = 0x80000001,
HKEY_LOCAL_MACHINE = 0x80000002,
HKEY_USERS = 0x80000003
}
[DllImport("advapi32.dll")]
private static extern int RegSetKeyValue(
HKEY hkey,
string lpSubKey,
string lpValueName,
UInt32 type,
byte[] data,
UInt32 dataLength
);
public static void SetNoneValue(HKEY hkey, string subkey, string valuename, byte[] bytes)
{
int rc = RegSetKeyValue(hkey, subkey, valuename, 0 /* REG_NONE */, bytes, (UInt32) (bytes == null ? 0 : bytes.Length));
if (rc != 0) {
// Access the error code in PowerShell with $Error[0].Exception.InnerException.NativeErrorCode
throw new System.ComponentModel.Win32Exception(rc);
}
}
// Overload that creates an empty value.
// Note: .NET 2 doesn't support optional parameters, so an explicit overload is required.
public static void SetNoneValue(HKEY hkey, string subkey, string valuename) {
SetNoneValue(hkey, subkey, valuename, null);
}
'#
Sample calls:
# Create an empty REG_NONE value named 'bar1' in key HKEY_CURRENT_USER\foo.
[WinApiHelper.Registry]::SetNoneValue('HKEY_CURRENT_USER', 'foo', 'bar1')
# Create a REG_NONE value named 'bar2' with a byte array.
[WinApiHelper.Registry]::SetNoneValue('HKEY_CURRENT_USER', 'foo', 'bar2', [byte[]] (42, 43))
I have to manipulate (including get and set text from) an accounting system using Powershell.
The process has a window which contain a grid-like container (the one with blue background colour in the screenshot).
The container contains some Text fields and Combo-boxes.
I tried different ways to get the UI controls(The Text fields/'Edit' Controls in the container).
I tried UIAutomation as follow but fail to found any Text field/'Edit' Control but found the Comobo-box.
Add-Type -AssemblyName UIAutomationClient
$ele=[System.Windows.Automation.AutomationElement]::FromHandle($hwnd)
$elecol=$ele.FindAll([System.Windows.Automation.TreeScope]::Descendants,
[System.Windows.Automation.Condition]::TrueCondition)
for ($i=0;$i -lt $elecol.count;$i++){$elecol[$i].Current} #Only found Scroll Bars & Combo
If look into the "AutomationElement.Current" of container itself ($ele.Current), it looks like the following.
ControlType : System.Windows.Automation.ControlType
LocalizedControlType : pane
Name :
AcceleratorKey :
AccessKey :
HasKeyboardFocus : False
IsKeyboardFocusable : False
IsEnabled : True
BoundingRectangle : 350,1658,2830,443
HelpText :
IsControlElement : True
IsContentElement : True
LabeledBy :
AutomationId :
ItemType :
IsPassword : False
ClassName : AfxGWOleControl42
NativeWindowHandle : 3409268
ProcessId : 11656
IsOffscreen : False
Orientation : None
FrameworkId : Win32
IsRequiredForForm : False
ItemStatus :
And if looks into the supported Patterns ($ele.GetSupportedPatterns()) of the container, it shows nothing.
I also tried using WinAPI to Enum All Child Windows but found No Text field/'Edit' Control too.
function Enum-ChildWindows{
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline = $true)]
[intPtr]$Hwnd
)
BEGIN{
if (("EnumChildWindowsAPI" -as [type]) -eq $null){
Add-Type #"
using System; // namespace "IntPtr"
using System.Runtime.InteropServices; // namespace "DLLImport"
using System.Collections.Generic; // namespace "List"
public class EnumChildWindowsAPI
{
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc,GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
return true;
}
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
}
"#
}
}
PROCESS{
return [EnumChildWindowsAPI]::GetChildWindows($Hwnd)
}
}
And of course, sending WM_SETTEXT message to the container is also not working.
Watching into the Spy++, the class name of the grid-like container is "afxGWOleControl", shown as follow.
An interesting thing is, the combo box "window" appear in Spy++ only when it is on selected.
Is there any way to edit/read the text field inside the container?
I wrote TCM for some calculation on AXI interfaces. TCM body is completely same for each interface but sampling event is different.
Is it possible to create one TCM and run it multiple times with different sampling events (clocks)?
Every TCM you start, creates its own thread.
You can run with different sampling events by changing the sampling event on an instance basis.
E.g. you have 2 instances of a monitor with a TCM running on sampling event #sample. you can modify the event using aspect orientation (here using the name aspect).
<'
type m_name : [mon1, mon2];
unit mon {
name : m_name; // using this aspect to distinguish instances
event sample;
tcm()#sample is {
while (TRUE) {
message(LOW, "TCM running in " , me);
wait;
};
};
run() is also {
start tcm();
};
};
extend sys {
// create an event running at half sys.any speed
!flag: bool;
on sys.any { flag = not flag;};
event clk is true(flag)#sys.any;
// 2 mon instances with different names
m1 : mon is instance;
keep m1.name == mon1;
m2 : mon is instance;
keep m2.name == mon2;
};
// change sampling events per instance
extend mon1'name mon {
event sample is only #sys.any;
};
extend mon2'name mon {
event sample is only #get_enclosing_unit(sys).clk;
};
'>
I'm trying to set the screen resolution via script (Powershell).
I found the cmdlet Set-DisplayResolution, which should work on Server 2012/R2 and 8/8.1 (where it won't work), and it also didn't work on Windows 10 PS 5.0.
I also had a look at
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Screen]::AllScreens
and
[System.Windows.Forms.Screen]::PrimaryScreen
but it showed weird output:
BitsPerPixel : 32
Bounds : {X=0,Y=0,Width=2000,Height=1333}
DeviceName : \\.\DISPLAY1
Primary : True
WorkingArea : {X=0,Y=0,Width=2000,Height=1293}
I am running a 3000x2000 resolution. Even after I changed my display to 1920x1080 the output stays the same.
After a longer search I found this script, which does the job using win32 API. Is there a more handy way for doing this, as this Set-DisplayResolution just running on Windows 10 Installation?
I also would like to set the UI scaling of Windows 10 (like 150%).
And for sure, i would like to know, why the AllScreens and PrimaryScreen methods of [System.Windows.Forms.Screen] aren't functioning properly.
Refer below script to change display resolution on Windows 10. PowerShell server core does not supported on windows 10. You can use below script
Important : you can provide display resolution at end of the script
currently it is set as Set-ScreenResolution -Width 1920 -Height 1080. You can change these values. Copy this complete script and save as Set-ScreenResolution.ps1 and execute using PowerShell. Make sure you Run powershell as admin
Function Set-ScreenResolution {
<#
.Synopsis
Sets the Screen Resolution of the primary monitor
.Description
Uses Pinvoke and ChangeDisplaySettings Win32API to make the change
.Example
Set-ScreenResolution -Width 1024 -Height 768
#>
param (
[Parameter(Mandatory=$true,
Position = 0)]
[int]
$Width,
[Parameter(Mandatory=$true,
Position = 1)]
[int]
$Height
)
$pinvokeCode = #"
using System;
using System.Runtime.InteropServices;
namespace Resolution
{
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
class User_32
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
}
public class PrmaryScreenResolution
{
static public string ChangeResolution(int width, int height)
{
DEVMODE1 dm = GetDevMode1();
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
dm.dmPelsWidth = width;
dm.dmPelsHeight = height;
int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);
if (iRet == User_32.DISP_CHANGE_FAILED)
{
return "Unable To Process Your Request. Sorry For This Inconvenience.";
}
else
{
iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);
switch (iRet)
{
case User_32.DISP_CHANGE_SUCCESSFUL:
{
return "Success";
}
case User_32.DISP_CHANGE_RESTART:
{
return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";
}
default:
{
return "Failed To Change The Resolution";
}
}
}
}
else
{
return "Failed To Change The Resolution.";
}
}
private static DEVMODE1 GetDevMode1()
{
DEVMODE1 dm = new DEVMODE1();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
return dm;
}
}
}
"#
Add-Type $pinvokeCode -ErrorAction SilentlyContinue
[Resolution.PrmaryScreenResolution]::ChangeResolution($width,$height)
}
Set-ScreenResolution -Width 1920 -Height 1080
Sorry to tell, but it's not possible with powershell:
[System.Windows.Forms.Screen] - the namespace says all you need to understand: This namespace refers to the display area for the application you've coded as an windows form (Usefull, if you have to change the windows-size within your application)
The Cmdlet Set-Displayresolution only works on Windows Server 2016 Core (or any other Core-Server in the future). It is documented on Technet : https://technet.microsoft.com/de-de/library/jj603036(v=wps.630).aspx
The workaround to use Win32-API, that you found earlier, looks like the best solution you could get.
A bit late, but depending on how you need the resolution set you could use AHK (scripting language). This would require a script opening the display settings dialog and sending clicks or keystrokes to it. If you're interested I can give more information
Update:
First, you have to have AutoHotKey installed on your computer (this is straightforward enough to just Google). Next, use a script to send keyboard input to the control panel display settings. It might look something like this:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#SingleInstance, force
detecthiddenwindows, on
; Use command prompt to open display settings
Run, %comspec% \k,,hide, cmd_pid
WinWait, ahk_pid %cmd_pid%
ControlSend, , control desk.cpl`n, ahk_pid %cmd_pid%
; Wait for display settings to open
WinWaitActive, Settings
sleep, 2000
; Send the appropriate key strokes to the settings menu to change the resolution
Send,{Tab 3}
sleep 100
Send,{Enter}
sleep 100
; Change this as needed to move to the desired display settings
Send,{Down 2}
sleep 100
Send,{Enter}
return
i am trying to use a powershell script that allows me to change the user account and password a specific service runs under.
$account="domain\account"
$password="password"
$svc=gwmi win32_service -filter "name='MyService'"
$svc.change($null,$null,$null,$null,$null,$false,$account,$password,$null,$null,$null)
I could check that the account was changed but when i tried to run the service from the Service.msc GUI it fails with a logon failure.
If I use to start the service from the script itself i get the following error.
$svc.StartService()
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0
PSComputerName :
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 15
PSComputerName :
According to microsoft it is a logon error : Return Value 15.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384901%28v=vs.85%29.aspx
I have verified the password a millions time and when I copy and paste the password using the GUI it just works.
May be i am missing something in my script. (SecurityPolicy is unrestricted on this machine)
You need to set the SeServiceLogonRight privilege on the user before setting the service account.
Set-Privileges $account "SeServiceLogonRight"
$svc=gwmi win32_service -filter "name='MyService'"
$svc.change($null,$null,$null,$null,$null,$false,$account,$password,$null,$null,$null)
An example of the Set-Privileges function which uses LSA:
function Set-Privileges
{
param(
$username,
$Privilege
)
# C# code from http://www.codeproject.com/Articles/4863/LSA-Functions-Privileges-and-Impersonation
$Source = #"
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace Privileges {
public class LsaUtility {
// Import the LSA functions
[DllImport("advapi32.dll", PreserveSig=true)]
private static extern UInt32 LsaOpenPolicy(
ref LSA_UNICODE_STRING SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
Int32 DesiredAccess,
out IntPtr PolicyHandle
);
[DllImport("advapi32.dll", SetLastError=true, PreserveSig=true)]
private static extern int LsaAddAccountRights(
IntPtr PolicyHandle,
IntPtr AccountSid,
LSA_UNICODE_STRING[] UserRights,
int CountOfRights);
[DllImport("advapi32")]
public static extern void FreeSid(IntPtr pSid);
[DllImport( "advapi32.dll", CharSet=CharSet.Auto, SetLastError=true, PreserveSig=true)]
private static extern bool LookupAccountName(
string lpSystemName, string lpAccountName,
IntPtr psid,
ref int cbsid,
StringBuilder domainName, ref int cbdomainLength, ref int use );
[DllImport( "advapi32.dll")]
private static extern bool IsValidSid(IntPtr pSid);
[DllImport("advapi32.dll")]
private static extern int LsaClose(IntPtr ObjectHandle);
[DllImport("kernel32.dll")]
private static extern int GetLastError();
[DllImport("advapi32.dll")]
private static extern int LsaNtStatusToWinError(int status);
// define the structures
[StructLayout(LayoutKind.Sequential)]
private struct LSA_UNICODE_STRING {
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
private struct LSA_OBJECT_ATTRIBUTES{
public int Length;
public IntPtr RootDirectory;
public LSA_UNICODE_STRING ObjectName;
public UInt32 Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;}
// enum all policies
private enum LSA_AccessPolicy : long{
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
POLICY_TRUST_ADMIN = 0x00000008L,
POLICY_CREATE_ACCOUNT = 0x00000010L,
POLICY_CREATE_SECRET = 0x00000020L,
POLICY_CREATE_PRIVILEGE = 0x00000040L,
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
POLICY_SERVER_ADMIN = 0x00000400L,
POLICY_LOOKUP_NAMES = 0x00000800L,
POLICY_NOTIFICATION = 0x00001000L
}
/// <summary>Adds a privilege to an account</summary>
/// <param name="accountName">Name of an account - "domain\account" or only "account"</param>
/// <param name="privilegeName">Name ofthe privilege</param>
/// <returns>The windows error code returned by LsaAddAccountRights</returns>
public static int SetRight(String accountName, String privilegeName){
int winErrorCode = 0; //contains the last error
//pointer an size for the SID
IntPtr sid = IntPtr.Zero;
int sidSize = 0;
//StringBuilder and size for the domain name
StringBuilder domainName = new StringBuilder();
int nameSize = 0;
//account-type variable for lookup
int accountType = 0;
//get required buffer size
LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType);
//allocate buffers
domainName = new StringBuilder(nameSize);
sid = Marshal.AllocHGlobal(sidSize);
//lookup the SID for the account
bool result = LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType);
//say what you're doing for debug
//Console.WriteLine("LookupAccountName result = "+result);
//Console.WriteLine("IsValidSid: "+IsValidSid(sid));
//Console.WriteLine("LookupAccountName domainName: "+domainName.ToString());
if( ! result ){
winErrorCode = GetLastError();
Console.WriteLine("LookupAccountName failed: "+ winErrorCode);
}else{
//initialize an empty unicode-string
LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();
//combine all policies
int access = (int)(
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
LSA_AccessPolicy.POLICY_CREATE_SECRET |
LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
LSA_AccessPolicy.POLICY_NOTIFICATION |
LSA_AccessPolicy.POLICY_SERVER_ADMIN |
LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
LSA_AccessPolicy.POLICY_TRUST_ADMIN |
LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
);
//initialize a pointer for the policy handle
IntPtr policyHandle = IntPtr.Zero;
//these attributes are not used, but LsaOpenPolicy wants them to exists
LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
ObjectAttributes.Length = 0;
ObjectAttributes.RootDirectory = IntPtr.Zero;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
//get a policy handle
int resultPolicy = (int)LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
winErrorCode = LsaNtStatusToWinError(resultPolicy);
if(winErrorCode != 0){
Console.WriteLine("OpenPolicy failed: "+ winErrorCode);
}else{
//Now that we have the SID an the policy,
//we can add rights to the account.
//initialize an unicode-string for the privilege name
LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1];
userRights[0] = new LSA_UNICODE_STRING();
userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName);
userRights[0].Length = (UInt16)( privilegeName.Length * UnicodeEncoding.CharSize );
userRights[0].MaximumLength = (UInt16)( (privilegeName.Length+1) * UnicodeEncoding.CharSize );
//add the right to the account
int res = LsaAddAccountRights(policyHandle, sid, userRights, 1);
winErrorCode = LsaNtStatusToWinError(res);
if(winErrorCode != 0){
Console.WriteLine("LsaAddAccountRights failed: "+ winErrorCode);
}else{
Console.WriteLine("LsaAddAccountRights successful");
}
LsaClose(policyHandle);
}
FreeSid(sid);
}
return winErrorCode;
}
}
}
"#
Add-Type -TypeDefinition $Source -Language CSharp
[Privileges.LsaUtility]::SetRight($username, $Privilege) | Out-Null
}
Not entirely relevent to this thread but could be useful to someone searching for this type of script.
PowerShell script to scan a computer/server find a service running under a specific account and stop the service, change the password, and then restrart the service.
I used the ListServices.psm1 module, http://gallery.technet.microsoft.com/scriptcenter/How-to-Clear-Printing-21d59516, to make the task easier for me. One quick note which took me a good 15 minutes to troubleshoot, it appears that if one is trying to set a password with a dollar symbol ($) in it, contain it within 'single quotes' not "double quotes"
Import-Module "C:\Tools\ListServices.psm1"
$pass = 'H:5Th7$!pc'
$Username = "abcservice"
$compName = gc env:computername
$newpass = [ADSI]"WinNT://$compName/$Username,user"
$newpass.SetPassword($pass)
$newpass.SetInfo()
Get-OSCServiceList -ComputerName "$compName" -UserName "$Username" | select Name | foreach { $_.Name} | Out-file -FilePath "C:\servicelist\service.txt"
foreach ($name in (Get-Content -Path "C:\servicelist\service.txt")) {
Write-Host "$name"
Stop-Service "$name"
Set-OSCServicePSW -ComputerName "$compName" -ServiceName $name -UserName ".\$Username" - NewPassWord $pass
Start-Service "$name"
}
HTH someone out there.
If you are just updating the password for the service account, and not changing which account runs the service, you might have more luck just changing the password itself. I've had success with this call to Win32_Service.Change():
$service.Change($Null,$Null,$Null,$Null,$Null,$Null,$Null,$Password)
This has consistently worked for me to update passwords.
Have you tried stopping the service before changing the password?
The following is working for me
$account="domain\account"
$password="password"
$svc=gwmi win32_service -filter "name='MyService'"
$svc.StopService();
$result = $svc.change($null,$null,$null,$null,$null,$false,$account,$password,$null,$null,$null)
if ($result.ReturnValue -eq '0') {write-host "Password changed"} else {write-host "Error: $result.ReturnValue"};
$svc.StartService();
I suspect that your password probably has at least one character that has special meaning in an interpolated string. Try single-quoting:
$password='password'
In general, it's a better habit to use single quotes by default, and only use double quotes when you specifically want to interpolate something.
BTW, also verify that you're using the correct service name. You need to use the Name property not the DisplayName. Try gwmi win32_service -filter "name='MyService'" at the prompt and make sure that doesn't return an error. It's probably the single vs. double quoting issue, though.
I know this issue was posted several years ago, however, I just encountered the same exact issue, with nearly identical code, resulting in the exact same returns.
The installer that I am using utilizes subinacl.exe to set permissions. The following article explains how to set those permissions:
http://www.waynezim.com/2010/02/how-to-set-permission-on-a-service-using-subinacl/
I simply added the 'i' switch in installation, and added the user to the appropriate group (if applicable). Considering the age of the article, I hope someone finds this useful.