Search notes:

Powershell module: WinConfig

The PowerShell module WinConfig allows to minimally configure some aspects of Windows.

Functions

clear-environmentVariable Remove an environment variable
set-environmentVariable Set an environment variable
add-dirToPath Add a directory to the PATH environment variable
remove-dirFromPath Remove a directory from the PATH environment variable
add-toPathExt Add an extension environment variable PATHEXT
publish-environmentVariables Apply changes to environment variables (send WM_WININICHANGE with SendMessageTimeout)
hide-NewsAndInterest Hide 'News and Interest' from the Taskbar

Source code

WinConfig.psm1

set-strictMode -version 3

function set-environmentVariable {

   param(
      [string] $name,
      [string] $value,
      [switch] $machine
   )

   [EnvironmentVariableTarget] $tgt = 'user'
   if ($machine) {             $tgt = 'machine' }

   [environment]::setEnvironmentVariable($name, $value, $tgt)
 #  Add new value also to process so that it is immediately available
   [environment]::setEnvironmentVariable($name, $value, 'process')

   publish-environmentVariables
}

function remove-environmentVariable {

   param(
      [string] $name,
      [switch] $machine
   )

   [EnvironmentVariableTarget] $tgt = 'user'
   if ($machine) {             $tgt = 'machine' }

   [environment]::setEnvironmentVariable($name, '', $tgt)

   invoke-expression "`$env:$name = ''"
   publish-environmentVariables
}

function add-dirToPath {

   param(
      [string]                    $dir,
      [switch]                    $machine,
    # [EnvironmentVariableTarget] $tgt = 'user', # or 'machine' (but probably not 'process')
      [switch]                    $psModulePath
   )

   if (-not (test-path -pathType container $dir) ) {
      write-textInConsoleWarningColor "Directory $dir does not exist"
      return
   }

  [EnvironmentVariableTarget] $tgt = 'user'
   if ($machine) {
      $tgt = 'machine'
   }

   $envVar = 'PATH'
   if ($psModulePath) {
      $envVar = 'PSModulePath'
   }

   $path = [environment]::getEnvironmentVariable($envVar, $tgt)
  [environment]::setEnvironmentVariable($envVar, "$dir;$path", $tgt)

   $pathBoth = [environment]::getEnvironmentVariable($envVar, 'machine') + ';' + [environment]::getEnvironmentVariable($envVar, 'user')
  [environment]::setEnvironmentVariable($envVar, $pathBoth, 'process')

   publish-environmentVariables
}

function add-toPathExt {

 #
 # TODO: apparently, the user's PATHEXT value shadows the system's value (if the user's is set)
 #

   param(
      [string] $ext
   )

   if ($ext -notMatch '^\.') {
      $ext = ".$ext"
   }

   $ext = $ext.ToUpper()

#  if ([System.Environment]::GetEnvironmentVariable('PATHEXT', 'user')) {
#     write-textInConsoleWarningColor "PATHEXT is shadowed by user variable"
#  }

   $cur_exts_reg = [System.Environment]::GetEnvironmentVariable('PATHEXT', 'user')


   $cur_exts_ary = $cur_exts_reg -split ';'
   if ($cur_exts_ary.Contains($ext)) {
      write-host "$ext is already in PATHEXT"
      return
   }

   $pathext = "$cur_exts_reg;$ext"
  [Environment]::SetEnvironmentVariable('PATHEXT', $pathext, 'user')

   invoke-expression "`$env:PATHEXT = '$pathext'"
   publish-environmentVariables

}

function remove-dirFromPath {

   param(
      [string]                    $dir,
      [EnvironmentVariableTarget] $tgt = 'user'
   )

 #
 # The parameter firstOnly is used to remove only one
 # occurence of the directory.
 # It is indended to be used if a directory has
 # duplicate entries in the PATH environment variable.
 #

   $pathsOld = [environment]::getEnvironmentVariable('PATH', $tgt) -split ';'
   $pathsNew = @()

   foreach ($dir_ in $pathsOld) {
      if (-not ($dir_ -eq $dir)) {
         $pathsNew += $dir_
      }
   }

   $pathsNew -join ';'

  [environment]::setEnvironmentVariable('PATH', ($pathsNew -join ';'), $tgt)

#  invoke-expression "`$env:PATH = '$([environment]::getEnvironmentVariable('PATH', 'machine'));$([environment]::getEnvironmentVariable('PATH', 'machine'))'"
   publish-environmentVariables
}

function hide-NewsAndInterest {

   set-itemProperty hkcu:\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds ShellFeedsTaskbarViewMode 2

}

function publish-environmentVariables {
 #
 #  https://renenyffenegger.ch/notes/Windows/registry/environment-variables
 #  https://github.com/ReneNyffenegger/about-Windows-Registry/blob/master/HKEY_CURRENT_USER/Environment/apply-changes.ps1
 #

    $funcDef = @'

    [DllImport("user32.dll", SetLastError = true, CharSet=CharSet.Auto)]

     public static extern IntPtr SendMessageTimeout (
        IntPtr     hWnd,
        uint       msg,
        UIntPtr    wParam,
        string     lParam,
        uint       fuFlags,
        uint       uTimeout,
    out UIntPtr    lpdwResult
     );

'@

   $funcRef = add-type -namespace WinAPI -name functions -memberDefinition $funcDef

   $HWND_BROADCAST   = [intPtr] 0xFFFF
   $WM_SETTINGCHANGE =          0x001A  # Same as WM_WININICHANGE
   $fuFlags          =               2  # SMTO_ABORTIFHUNG: return if receiving thread does not respond (hangs)
   $timeOutMs        =            1000  # Timeout in milli seconds
   $res              = [uIntPtr]::zero

 #
 # If the function succeeds, this value is non-zero.
 #
   $funcVal = [WinAPI.functions]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::zero, "Environment", $fuFlags, $timeOutMs, [ref] $res);

   if ($funcVal -eq 0) {
      write-host "SendMessageTimeout did not succeed, res= $res"
   }

}
Github repository ps-modules-WinConfig, path: /WinConfig.psm1

WinConfig.psd1

@{
   RootModule         = 'WinConfig.psm1'
   ModuleVersion      = '0.1'

   RequiredModules    = @(
   )

   RequiredAssemblies = @(
   )

   FunctionsToExport  = @(
      'set-environmentVariable', 'clear-environmentVariable',  # Set/remove an environment variable
      'add-dirToPath'               ,                          # Add a directory to the PATH environment variable
      'remove-dirFromPath'          ,                          # Remove a directory from the PATH environment variable
      'add-toPathExt'               ,                          # Add an extension environment variable PATHEXT
      'publish-environmentVariables',                          # Apply changes to environment variables (send WM_WININICHANGE with SendMessageTimeout)
      'hide-NewsAndInterest'                                   # Hide 'News and Interest' from the Taskbar
   )

   ScriptsToProcess   = @(
   )

   AliasesToExport    = @(
   )
}
Github repository ps-modules-WinConfig, path: /WinConfig.psd1

See also

René's simple PowerShell modules

Links

https://github.com/jaapbrasser/CustomizeWindows11

Index