A quick PowerShell tip

I have a bunch of PowerShell functions that I stick in my $profile file. Simple stuff, things to make my day to day development work easier. With my sieve-like memory, I need a quick way to see the functions. So I wrote a script named “mine.ps1” and it’s basically a tiny help file.  It has stuff like this

write-host Commands -ForegroundColor White
write-host "get-guid-clipboard" -ForegroundColor Yellow
write-host "set-alias lsd get-by-date" -ForegroundColor Yellow
write-host "Set-Alias touch Set-FileTime" -ForegroundColor Yellow

In my $profile, I define those functions. They could (and should) be in a separate file, but I’m lazy. This is part of my PowerShell profile:

function Set-FileTime{
    param(
      [string[]]$paths,
      [bool]$only_modification = $false,
      [bool]$only_access = $false
    )
  
    begin {
      function updateFileSystemInfo([System.IO.FileSystemInfo]$fsInfo) {
        $datetime = get-date
        if ( $only_access )
        {
           $fsInfo.LastAccessTime = $datetime
        }
        elseif ( $only_modification )
        {
           $fsInfo.LastWriteTime = $datetime
        }
        else
        {
           $fsInfo.CreationTime = $datetime
           $fsInfo.LastWriteTime = $datetime
           $fsInfo.LastAccessTime = $datetime
         }
      }
     
      function touchExistingFile($arg) {
        if ($arg -is [System.IO.FileSystemInfo]) {
          updateFileSystemInfo($arg)
        }
        else {
          $resolvedPaths = resolve-path $arg
          foreach ($rpath in $resolvedPaths) {
            if (test-path -type Container $rpath) {
              $fsInfo = new-object System.IO.DirectoryInfo($rpath)
            }
            else {
              $fsInfo = new-object System.IO.FileInfo($rpath)
            }
            updateFileSystemInfo($fsInfo)
          }
        }
      }
     
      function touchNewFile([string]$path) {
        #$null > $path
        Set-Content -Path $path -value $null;
      }
    }
   
    process {
      if ($_) {
        if (test-path $_) {
          touchExistingFile($_)
        }
        else {
          touchNewFile($_)
        }
      }
    }
   
    end {
      if ($paths) {
        foreach ($path in $paths) {
          if (test-path $path) {
            touchExistingFile($path)
          }
          else {
            touchNewFile($path)
          }
        }
      }
    }
  }

function get-by-date {get-childitem | sort LastWriteTime }
function get-guid-clipboard { [guid]::NewGuid() | Set-Clipboard }
set-alias lsd get-by-date
Set-Alias touch Set-FileTime
Set-Alias -Name guidc -Value get-guid-clipboard -Description "Get a GUID and copy it to the clipboard"
function get-mine {. d:\\scripts\mine.ps1}
write-host "Type 'get-mine' for my local functions"
[System.Net.Dns]::GetHostByName($env:computerName).HostName.ToLower()

The touch functions came from the ss64.com site. I end by displaying the current machine name. When you remote into a box of boxes, it’s good to know where you currently are. Now when I fire up a new shell, I’ll see something like this:

PowerShell 7.1.3
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

Type 'get-mine' for my local functions
uberbox
Loading personal and system profiles took 929ms.

Checking Hypervisor status with PowerShell

Image courtesy of Serge Melki

I needed to find a quick way to see which hypervisor was installed.  I bounce between different development machines and some have Hyper-V enabled and some have Intel’s HAXM driver installed.  Both assist with virtual machines, but they can’t be used together.  I used to be 100% Hyper-V with running virtual machines and Android emulators.  The Microsoft Android Emulator used to be very good, but is suffering from a fair amount of bit rot.  In the meanwhile, Google’s Android Emulator has gone from being a great of sitting and watching something load very slowly to a tool that that you can use in real time.

Microsoft’s Android Emulator requires Hyper-V and Google’s Emulator really needs HAXM in order to have any level of performance.  Since I bound around from machine to machine (with the occasional repave), I wanted a quick way to see which hypervisor is installed.  Hyper-V requires a some work to turn on and off. HAXM is a kernel driver.  So I wrote a quick PowerShell script to report the status of each Hypervisor

$services = 'intelhaxm', 'vmicheartbeat'

$d = [System.ServiceProcess.ServiceController]::GetDevices() | ? {
  $services -contains $_.Name
}

$s = Get-Service | ? {
  $services -contains $_.Name
}

$d
$s

The first line just defines an array of names to match one. The next block of code uses GetDevices() to return the status of the HAXM driver. The block that follows returns the status of the Hyper-V Heartbeat Service. The last part just dumps out the results.

An alternative way is to pass the service name to Get-Service and it will return the status for the specified service. The problem is that it will error out if the specified service does not exist. And while that error message is a status report, it’s an ugly way to get that information

I named the script “hyper-stat.ps1” and when I run it on a machine with HAXM running, I get the following output

.\hyper-stat.ps1

Status   Name               DisplayName                           
------   ----               -----------                           
Running  IntelHaxm          Intel HAXM Service 

On a machine with Hyper-V and no HAXM, I get this

.\hyperv-stat.ps1

Status   Name               DisplayName                           
------   ----               -----------                           
Running  vmicheartbeat      Hyper-V Heartbeat Service    

If I disable Hyper-V, I would get the following:

.\hyperv-stat.ps1

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  vmicheartbeat      Hyper-V Heartbeat Service             

There are few ways of scripting this task. This one was simple and I have it on the machines that I use for coding.

Edit: Right after posting this, I realized it didn’t actually work. I was originally reporting on the status of vmms, the Hyper-V Virtual Machine Management Service. If Hyper-V is installed, that service will always be running, even when Hyper-V is not enabled. The Hyper-V Heartbeat service is a better test for seeing if Hyper-V is enabled.