Showing posts with label CIM. Show all posts
Showing posts with label CIM. Show all posts

2025-02-24

Set Windows pagefile

When troubleshooting memory issues it sometimes is necessary to change the Windows pagefile to something different that the default settings. In this case I would like the pagefile to have the same size as the amount of physical memory and be placed on another drive.

(Default Windows pagefile)

Add custom pagefile

To disable „Automatically manage paging file size for all drives“ WMI can be used with the Win32_ComputerSystem class. I use it with a WMI CmdLet and not a CIM CmdLet as the put-method does not work with a CIM CmdLet.

$PageFile = Get-WmiObject -Class Win32_ComputerSystem -EnableAllPrivileges
$PageFile.AutomaticManagedPagefile = $false
$PageFile.put() | Out-Null

When the automation is disabled then the pagefile can be configured. In this case I am setting Initial and Maximum size both to the amount of physical memory. It is recommend (1) that the max pagefile is set to the amount of physical memory plus 257 MB. All this can be done with CIM and WMI CmdLets. The memory size from Win32_PhysicalMemory is in Bytes where the properties to Win32_PageFileSetting are in MB and this is why I convert to MB in the script.

$PhysicalMemory = Get-CimInstance -ClassName Win32_PhysicalMemory
[int]$PageFileSize = 0
foreach ( $Device in $PhysicalMemory ) { $PageFileSize += $Device.Capacity/1MB }
$PageFileSize += 257
"Setting PageFile size to $PageFileSize MB..."

$PageFileSet = Get-WmiObject -Class Win32_PageFileSetting
#$PageFileSet | fl *
$PageFileSet.InitialSize = $PageFileSize
$PageFileSet.MaximumSize = $PageFileSize
$PageFileSet.Put() | Out-Null

(Windows pagefile custom configuration)

If the server is with NUMA configuration then Win32_PhysicalMemory will return an array of memory devices. This is why I traverse the output with foreach. In my case the computer is a virtual machine with eight vCores on eight vSockets and it looks like Windows Server (2016) split that in four vNUMA nodes as I get an array of four elements from Win32_PhysicalMemory. My workstation is the host and runs with one 12C/24T processor.

There must be enough free storage. If that is not available the Win32_PageFileSetting.Put() will fail with this not usefull message:

Exception calling "Put" with "0" argument(s): "Value out of range "
At line:12 char:1
+ $PageFileSet.Put() | Out-Null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

To activate the configuration the server needs a reboot.

(Windows pagefile custom configuration activated)

The custom pagefile is added in the right place. But the default pagefile still exist.

Remove default pagefile

The default pagefile is removed with the method Delete() to the specific selected default pagefile by a WQL statement.

$defaultPageFile = Get-WmiObject -Query "SELECT * FROM Win32_PageFileSetting WHERE Name = 'C:\\pagefile.sys'"
#$defaultPageFile | fl *
$defaultPageFile.Delete()

This takes effect with another reboot. This reboot also remove the file "pagefile.sys" from the root of the C-drive.


(Windows default pagefile deleted)

The methods to a WMI object like from Win32_PageFileSetting above does not show with Get-Member. But the documentation to the interface IWbemClassObject lists and describe the general methods to a WMI object.

Notes

(1) Microsoft: Overview of memory dump file options for Windows > Complete memory dump.

History

2025-06-01 : Custom pagefile and default pagefile are differelt.

2025-04-29 : 257 MB addition to pagefile size with reference to (1).

2025-02-24 : Post created

2015-11-05

SQL Server Native Client WMI name

I am developing a SQL Server deployment package. And again I do not hit the nail in the first stroke.
This makes me install - and uninstall - SQL Server components several times. Rather quickly I get tired by clicking through Uninstall in Windows Control Panel. This can usually be fixed with a PowerShell script, but uninstalling SQL Server Native Client (SNAC) gave me some trouble.

To get the metadata on the installed programs through CIM I created a variable to work on
$CimProduct = Get-CimInstance -ClassName Win32_Product -Filter "Name LIKE 'Microsoft SQL Server 2012 Native Client'"
But the result in $CimProduct was empty.

A general request showed me that SNAC is installed with the name that I filtered on
Get-CimInstance -ClassName Win32_Product -CimSession $CimSession
gave a long list which I have narrowed down here
Name             Caption                                              Vendor                                               Version
----             -------                                              ------                                               -------
...
Microsoft SQL... Microsoft SQL Server 2012 Native Client              Microsoft Corporation                                11.0.2100.60
...

Then I tried a more general filter
$CimProduct = Get-CimInstance -ClassName Win32_Product -Filter "Name LIKE '%Native Client%'"
"Name = '$($CimProduct.Name)'."

with success
Name = 'Microsoft SQL Server 2012 Native Client '.
Immediately it looked like the text that I filtered on in the beginning.
But notice the trailing space!
If I some day meet the Product Manager we have something to talk about ;-)

With the new knowledge I got the search right
$CimProduct = Get-CimInstance -ClassName Win32_Product -Filter "Name LIKE 'Microsoft SQL Server 2012 Native Client '"

Now I was able to uninstall SNAC in one line
$Uninstall = Invoke-CimMethod -Query "SELECT * FROM Win32_Product WHERE Name = 'Microsoft SQL Server 2012 Native Client '" -MethodName Uninstall
$Uninstall.ReturnValue

And with success
0