Showing posts with label Microsoft Windows. Show all posts
Showing posts with label Microsoft Windows. Show all posts

2025-10-20

New Windows Storage

Sometimes one just has to add new storage to a Windows installation. And in some cases like adding physical storage there are a few simple steps like below.

Values like disk number you can get from the disk handling GUI in Windows (right-click Windows).

 

1) Initialize disk

Initialize-Disk -Number 2 -PartitionStyle GPT

2) Create partition

New-Partition -DiskNumber 2 -UseMaximumSize -DriveLetter S

3) Format volume

Format-Volume -DriveLetter S -FileSystem NTFS -NewFileSystemLabel Spare -Full:$false -UseLargeFRS

If you are adding more than 8 TB or know that the storage mostly is for a few large files then add the CmdLet parameter -AllocationUnitSize 64KB. Add the CmdLet parameter -UseLargeFRS to use large File Record Segment (FRS) when files are created, altered and deleted often.

 

If the storage unit is reused from another Windows installation, then the unit can be wiped like this

Clear-Disk -Number 2 -RemoveData

If the disk holds one or more OEM recovery partition then add the CmdLet parameter -RemoveOEM.

 

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

2024-11-07

Reduce OS memory with BCDEdit

This is a quick description on how to reduce OS memory on virtual Windows Server 2016 from 128 GB to 48 GB without changing VM configuration. This can be done with the command BCDEdit.exe which is somewhat described by Microsoft in the documentation on bcdedit and the documents "BCDEdit Command-Line Options" and "BCDEdit Options Reference". The tool is a default tool in Microsoft Windows and is placed in the directory "C:\Windows\System32\".

The name of the tool referes to Boot Configuration Data, which is described somewhat in an old MSDN Vista document BCD.docx. Boot Configuration Data is a firmware independant data store with boot data. The store is placed in the system partition.

Reducing memory available to the OS is sometimes done, when you have an application that is not using all available memory, but is licensed by the memory amount available to the OS. And this is sometimes made worse by a computer with way too much memory that can't be reduced by ridiculous agreements.

Before

System Information (msinfo32.exe) on the guest VM. All installed memory is available to the OS:

Reduce OS Memory

Calculation: The number needed for the command is the amount of removed memory. In this case 128 GB - 48 GB = 80 GB. As the number must be in MB the corection is 80 GB * 1024 MB/GB = 81920 MB.

Start console (cmd.exe) as Administrator. PowerShell does not work. Enter the command line:

bcdedit /set {current} removememory 81920

  • bcdedit is shorthand on BCDEdit.edit.
  • /set is a option to BCDEdit described in BCDEdit /set.
  • {current} is a reference to the current boot entry.
  • removememory removes memory available to the Windows operating system.
  • 81920 is the amount of memory to remove from the OS in MB. See calculation above.

Reboot VM.

After

System Information on guest VM:

Task Manager on guest VM:

It shows both 128 GB and 48 GB even only 48 GB is available to the OS. This will confuse most operators and administrators.

Roll-Back

Start console as Administrator. And enter the command line:

bcdedit /deletevalue {current} removememory

Reboot VM.

And all the memory is available to the VM as shown by System Information.

Notes on System Configuration

Windows has the standard tool System Configuration where it looks like you also can reduce OS memory. Let me point out that this does not work as bcdedit /set removememory but like bcdedit /set truncatememory which is not as effective.

Disclaimer

This is not my own findings but given to me by the good colleague Ib Thornøe (LinkedIn)

2022-04-01

Check for pending restart

 Windows pending restart is unfortunately not a singular registration, but is in three differen places in the Windows Registry:

  • HKLM: SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired
  • HKLM: System\CurrentControlSet\Control\Session Manager, PendingFileRenameOperations
  • HKLM: SOFTWARE\CapaSystems\RestartStatus, Reboot
The last one is specific for the Capa (CapaSystems.dk) systems, that I have met in a IT infrastructure.

2019-03-27

Windows Storage Spaces

To look into Windows Storage Spaces on if and how to use it on a SQL Server database server I have added 5 SCSI disks to a virtual server running Windows Server 2016 on vmware Workstation.
Please notice that I am working with the local Windows Storage Spaces and not the networked Storage Spaces Direct (S2D). The physical disk on the host is a Samsung 970 Evo NVMe SSD also hosting the host OS Windows 10 Pro.

On these 5 disks I create a storage pool where I create 2 Virtual Disks of different size and with different allocation unit size. The allocation units are of different size with a SQL Server installation in mind.
Also the logical sector size in the storage pool is set to 4KB where the default is 512B. This is to see how easy it is to change this and maybe later experiment further with the impact of a larger logical sector size.

The storage pool is created with the CmdLet New-StoragePool:

New-StoragePool -FriendlyName Pool_00 -StorageSubSystemFriendlyName (Get-StorageSubSystem).FriendlyName -PhysicalDisks (Get-PhysicalDisk -CanPool $true) -LogicalSectorSizeDefault 4KB

The CmdLet return

FriendlyName OperationalStatus HealthStatus IsPrimordial IsReadOnly
------------ ----------------- ------------ ------------ ----------
Pool_00      OK                Healthy      False        False   


Then the first Virtual Disk is created with the CmdLet New-VirtualDisk:

New-VirtualDisk -StoragePoolFriendlyName Pool_00 -FriendlyName ProgramDisk -ResiliencySettingName Mirror -NumberOfDataCopies 3 -Size (42GB) -ProvisioningType Thin

This CmdLet return

FriendlyName ResiliencySettingName OperationalStatus HealthStatus IsManualAttach  Size
------------ --------------------- ----------------- ------------ --------------  ----
ProgramDisk  Mirror                OK                Healthy      False          42 GB


To create a partition on the Virtual Disk and format the volume with ReFS a small PowerShell script does it:

Get-VirtualDisk -FriendlyName ProgramDisk | Get-Disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -DriveLetter F -UseMaximumSize |
Format-Volume -NewFileSystemLabel Program -FileSystem ReFS


This small script return

DriveLetter FileSystemLabel FileSystem DriveType HealthStatus OperationalStatus SizeRemaining     Size
----------- --------------- ---------- --------- ------------ ----------------- -------------     ----
F           Program         ReFS       Fixed     Healthy      OK                     40.93 GB 41.81 GB


When the disk is created a dialog about formatting the drive might be shown like this


To check the volume I use the command-line tool fsutil:

.\fsutil.exe fsinfo refsinfo F:

The tool return

REFS Volume Serial Number :       0xee841e1a841de63d
REFS Version   :                  3.1
Number Sectors :                  0x0000000000a74000
Total Clusters :                  0x0000000000a74000
Free Clusters  :                  0x0000000000a3bb69
Total Reserved :                  0x0000000000018510
Bytes Per Sector  :               4096
Bytes Per Physical Sector :       4096
Bytes Per Cluster :               4096
Checksum Type:                    CHECKSUM_TYPE_NONE


The second Virtual Disk is created with

New-VirtualDisk -StoragePoolFriendlyName Pool_00 -FriendlyName DataDisk -ResiliencySettingName Mirror -NumberOfDataCopies 3 -Size (123GB) -ProvisioningType Thin

A return similar to last time

FriendlyName ResiliencySettingName OperationalStatus HealthStatus IsManualAttach   Size
------------ --------------------- ----------------- ------------ --------------   ----
DataDisk     Mirror                OK                Healthy      False          123 GB


The volume is created and formatted with the small script:

Get-VirtualDisk -FriendlyName DataDisk | Get-Disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -DriveLetter H -UseMaximumSize |
Format-Volume -NewFileSystemLabel Data -FileSystem ReFS -AllocationUnitSize 64KB


And the return is

DriveLetter FileSystemLabel FileSystem DriveType HealthStatus OperationalStatus SizeRemaining      Size
----------- --------------- ---------- --------- ------------ ----------------- -------------      ----
H           Data            ReFS       Fixed     Healthy      OK                    121.77 GB 122.81 GB


Check the volume

.\fsutil.exe fsinfo refsinfo H:

The tool return

REFS Volume Serial Number :       0x2620bb5220bb27a7
REFS Version   :                  3.1
Number Sectors :                  0x0000000001eb4000
Total Clusters :                  0x00000000001eb400
Free Clusters  :                  0x00000000001e710d
Total Reserved :                  0x00000000000027c8
Bytes Per Sector  :               4096
Bytes Per Physical Sector :       4096
Bytes Per Cluster :               65536
Checksum Type:                    CHECKSUM_TYPE_NONE


Discussion

This is just to look in the creation of a storage pool with different Virtual Disks in Windows Storage Spaces. Looking at performance and optimal configuration for SQL Server are other and later writings.

Please notice that Windows can't boot on a storage pool. This gives that you have to configure a more traditional storage for booting and running Windows. Here there is no difference between Windows Server and Windows desktop OS.

A quick thought though is that I think that I would avoid tiered storage. Just as in a SAN configuration for SQL Server.

2018-10-04

Access to vmware shared folders in PowerShell administrator session

When you define shared folders to a vmware guest as a drive they are also available to a PowerShell session as a drive. Usually the Z-drive. This you can see by the command "net use"

PS> net use
New connections will be remembered.

Status       Local     Remote                    Network
-------------------------------------------------------------------------------
             Z:        \\vmware-host\Shared Folders
                                                VMware Shared Folders
The command completed successfully.


But if the PowerShell session is a administrator session, you get something like a network error. This is because the share is not defined to the administrator session. If a "net use" is run and the result compared with the one from the normal user session you can see that the Z-drive is missing.

PS> net use
New connections will be remembered.

There are no entries in the list.


The drive is then mapped to the session. A new administrator session will also have the Z-drive mapped.

PS> net use Z: '\\vmware-host\shared folders'
The command completed successfully


It is possible to persist the mapping by the parameter "Persist", but you might experience that the persistance is a varying subject. I have not looked deeper into the details on this.
/persistent:{yes | no}

The short help on "net use" is available with the command:
net use /?
The longer help is available with the command:
net use /help

This is not only in PowerShell, but a general Windows UAC thing. You will have the somewhat same experience in other tools like Windows Shell (cmd) or Windows Scripting Host (WSH).

Setting the Z-drive with the PowerShell cmdlet New-PSDrive does not make the vmware shared folders available to administrator sessions.

2018-08-03

Manual update Windows Server 2016

I have to update Windows Server installations manually as they are used for sandbox installations on virtual machines, and some of the installations like ADDC I don't want to put on the internet. Also I don't take the time to build a WSUS installation to each sandbox installation or domain.

The otes on manually updates to Windows Server 2016 are personal and strictly coupled to my given installations. Experiences are then also rather personal, and the notes should not be used without review and test.

Updates are downloaded from Microsoft Update Catalog. A search for "Windows Server 2016" (link) and a sort on latest update date gives a nice list to pick from.
Usually updates are released to the catalog at the same time as to Windows Update. That is 2nd Tuesday of the month. Also called Patch Tuesday.


2018-07 Cumulative Update (KB4346877) fail with error message on the update not being "applicable".
Searching the error message I found this short and precise description from PDQ.com (link). It points to KB4132216 on a "Servicing stack update for Windows..." where the text mention stability improvements to "... an issue that might sometimes lead to incorrect checks for applicability during installation of Windows Updates...". The text is at first sight on Windows 10, but a lot of Windows Server 2016 updates are named Windows 10 in the KB articles and even the files in the installations.
The update can be downloaded from Microsoft Update Catalog (link). Installing the servicing stack update takes a few seconds, and after that the Cumulative Update runs as expected.
This takes several minutes and requires a server restart. The restart itself also takes several minutes.

2013-12-11

Temporary Windows file

Sometimes it can be usefull to create a temporary Windows file, that is more general available than a personal temporary user file.
If you use the environmental variablesTEMP“ or „TMP“ you get your personal folder for temporary files, e.g. „C:\Users\Niels\AppData\Local\Temp“. Both variables gives the same folder name.

To get the path of the more general folder of temporary files „C:\Windows\Temp“ you can use the environmental variables „SystemRoot“ or „windir“ and add the name of the Temp-folder in PowerShell like
"$Env:SystemRoot\Temp"

To create a unique and identifiable temporary file I usually add a timestamp to the filename like
.$(("{0:s}Z" -f $([System.DateTime]::UtcNow)).Replace(':', '_')).
The Z is to indicate that the timestamp is UTC. That is timezone Z also called Zulu time.
The Replace method of the formatted String-object is used to get rid of the colons in the standard format. A colon is not acceptep by Windows in a file name.

The name of a temporary file can be created in a single PowerShell statement
$TempFile = "$Env:SystemRoot\Temp\_temp.$(("{0:s}Z" -f $([System.DateTime]::UtcNow)).Replace(':', '_')).ps1"

Writing to the temporary file can be done in PowerShell with the cmdlet Out-File or PowerShell redirection operators.
The first line can be written without any terms, but the following lines must be added to preserve the existing contents of the temporary file.
The first line, that also creates the temporary file, can be written in PowerShell like
'1st line' | Out-File -FilePath $TempFile
A second line can be added using the cmdlet Out-File like
'2nd line' | Out-File -FilePath $TempFile -Append
A third line can be added with the PowerShell appending redirection operator like
'3rd line' >> $TempFile

With the three examples above a temporary file is created
C:\Windows\Temp\_temp.2013-12-11T15_33_50Z.ps1
The contents of the temporary file is
1st line
2nd line
3rd line


This simple technique can be used to create other temporary Windows files like text files or data (csv) files.