Tuesday, June 22, 2021

PowerShell Single Column to Multiple Columns

This thing will take a single column of text, split it up into columns and put it on screen - But it could be adapted easily to some other output.
A couple of things to note:

  • '$pad' is there for readability - so the columns have some padding.
  • '-HideTableHeaders'
  • The 'Function' items inside this, especially the 'ListToArray' comes in handy for me all the time. I dropped it in this way, just to share it in a way that that stood out.
  • This could be done in fewer lines, and I do like brevity, but I wanted to leave it more 'spelled' out, for illustrative purposes.

Using the 50 states to show it working.
Function '#of columns' "Data source"

Column2Columns 3 $Data
Column2Columns 5 $Data
Column2Columns 10 $Data

Examples below the code:

$Data = ("Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
Nebraska
Nevada
New Hampshire
New Jersey
New Mexico
New York
North Carolina
North Dakota
Ohio
Oklahoma
Oregon
Pennsylvania
Rhode Island
South Carolina
South Dakota
Tennessee
Texas
Utah
Vermont
Virginia
Washington
West Virginia
Wisconsin
Wyoming")

Function
Column2Columns {
################################
<#
.DESCRIPTION
      Takes a single column of data (as a string), splits it into a specified number of columns, as its output.

.EXAMPLE
    # Three columns
      Column2Columns 3 $Data

.EXAMPLE
    # Two columns
      Column2Columns 2 $Blah

.EXAMPLE
    # Four columns
    Column2Columns 4 $LongList
#>
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [int]  $Columns,
         [Parameter(Mandatory=$true, Position=1)]
         [string] $Data
    )

Function
ListToArray { ($Args).Split("`n|`r",[System.StringSplitOptions]::RemoveEmptyEntries) }
Function AddMembr {$Stack | Add-Member -membertype noteproperty -name "Item$Counter_Data" -Value "$_$pad"}
$pad = "    "
$Counter_Data = 0
$Columns_Array = @()
$Stack = new-object psobject

ListToArray
$Data |  % {
$Counter_Data++
  If ($Counter_Data -lt ($Columns)) { AddMembr }
  If ($Counter_Data -ge ($Columns)) { AddMembr
    $Counter_Data = 0
    $Columns_Array += $Stack
    $Stack = new-object psobject
  }
}

$Columns_Array
+= $Stack
$Columns_Array =  $Columns_Array | ? { !([string]::IsNullOrEmpty($_)) }
$Columns_Array | ft -HideTableHeaders
}
# END Function

 

Examples:



Wednesday, June 16, 2021

'ipconfig /all' - Posh version

I wanted a more comprehensive, and easier to read, output of a systems network settings, etc...

I have this set as a Function and it has an alias.

I call theses functions from both PoSh profiles.

This is what the output looks like:

The script:

Function Get-IP {

Write-Host "Fetching IP info..." -ForegroundColor Gray -BackgroundColor Black
$AdapterList = @()
Get-NetAdapter | ? {$_.InterfaceDescription -NOTmatch 'Bluetooth'| % {
$adapter = $_
$prefix = (Get-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex | ? {$_.ipv4address}).prefixlength
('1' * $prefix).PadRight(32, '0') | Out-Null;$bitString=('1' * $prefix).PadRight(32,'0'); $SnM=[String]::Empty
    for($i=0;$i -lt 32;$i+=8)
    {$byteString=$bitString.Substring($i,8); $SnM+="$([Convert]::ToInt32($byteString, 2))."}
If ((Get-NetIPInterface -InterfaceAlias $_.InterfaceAlias).Dhcp -eq "Enabled") {$DHCP = "DHCP"} else {$DHCP = "STATIC"}
$AdapterList += ((Get-NetIPConfiguration | ? {$_.InterfaceIndex -match "$($adapter.InterfaceIndex)"} | select
    @{Name='Alias';Expression ={$_.InterfaceAlias}},`
    @{Name='Status';Expression ={$_.NetAdapter.Status}},`
    @{Name='IPAddress';Expression ={"$($_.IPv4Address.IPAddress) ($DHCP)"}},`
    @{Name='SubnetMask';Expression ={"$($SnM.TrimEnd('.')) (/$prefix)"}},`
    @{Name='Gateway';Expression ={$_.IPv4DefaultGateway.NextHop}},`
    @{Name='DNSServer(s)';Expression ={$_.DNSServer.ServerAddresses}},`
    @{Name='MAC';Expression ={$adapter.MacAddress}},`
    @{Name='Index';Expression ={$_.InterfaceIndex}},`
    @{Name='Description';Expression ={$_.InterfaceDescription}}))
    }
Write-Host "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" -ForegroundColor Gray
$AdapterList | % {
$_ | % {
If ($_.IPAddress -match "169.") {
    $_.IPAddress = "($DHCP)"
    $_.SubnetMask = " - "
}

$Item00
= $_
($Item00 | Out-String).Split("`n|`r",[System.StringSplitOptions]::RemoveEmptyEntries) | % {
If ($Item00.Status -match "Disconnected") {Write-Host "█ " -fore Red -No }
If ($Item00.Status -match "Up") {Write-Host "¤ " -fore Green -No }
If ($_ -match "Index") {Write-Host " " $_ -ForegroundColor cyan}
If ($_ -match "Alias") {Write-Host " " $_ -ForegroundColor Yellow}
If ($_ -match ": Up") {Write-Host " " $_ -ForegroundColor Green}
If ($_ -match ": Disconnected") {Write-Host " " $_ -ForegroundColor Magenta}
If ($_ -NOTmatch "Index" -and $_ -NOTmatch "Alias" -and $_ -NOTmatch "Status") {Write-Host " " $_}
}

(
$Item00 | Out-String).Split("`n|`r",[System.StringSplitOptions]::RemoveEmptyEntries) | % {
    If ($_ -match "Alias" -and $_ -match "Wi-Fi" -and $Item00.Status -match "Up") {
        netsh wlan show interfaces | % {
            If ($_ -match "SSID" -and $_ -NOTmatch "BSSID") {$SSID = $_}
            If ($_ -match "State") {$State = $_}
            If ($_ -match "Signal") {$Signal = $_}
            If ($_ -match "Authentication") {$Auth = $_}
        }
            Function SplitWrite($arg0) {Write-Host ($arg0.Split(':')[1]).Trim() -Fore 11}
                Write-Host "             SSID: " -Fore 14 -No; SplitWrite $SSID
                Write-Host "            State: " -Fore 14 -No; SplitWrite $State
                Write-Host "           Signal: " -Fore 14 -No; SplitWrite $Signal
                Write-Host "             Auth: " -Fore 14 -No; SplitWrite $Auth
    }
}

}
Write-Host "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" -ForegroundColor Gray
}

}
# End Function Get-IP

set-alias
-name gip -value Get-IP


On GitHub: 
Get-IP.psm1

Friday, June 4, 2021

Set NumLock for All / Current user via Powershell

Keep in mind that the below commands can also be wrapped into an 'Invoke-Command' - You just need to make sure WinRM* is enabled on the remote computer - 

I'll list out below, how I deal with WinRM enablement.*

Get each of these values:

NOTE - Two different Registry locations; 'HKEY_USERS\.DEFAULT', and 'HKEY_CURRENT_USER'

(Get-ItemProperty -Path Registry::"HKEY_USERS\.DEFAULT\Control Panel\Keyboard" -Name InitialKeyboardIndicators).InitialKeyboardIndicators

(Get-ItemProperty -Path Registry::"HKEY_CURRENT_USER\Control Panel\Keyboard" -Name InitialKeyboardIndicators).InitialKeyboardIndicators 


If either of these are set to either '0', or '2147483648'...

Add '2' to them, and set the new value accordingly - 
So, '0' becomes '2'
And '2147483648' becomes '2147483650'

Examples:

Set-ItemProperty -Path Registry::"HKEY_USERS\.DEFAULT\Control Panel\Keyboard" -Name InitialKeyboardIndicators -Value 2

Set-ItemProperty -Path Registry::"HKEY_USERS\.DEFAULT\Control Panel\Keyboard" -Name InitialKeyboardIndicators -Value 2147483650

Set-ItemProperty -Path Registry::"HKEY_CURRENT_USER\Control Panel\Keyboard" -Name InitialKeyboardIndicators -Value 2

Set-ItemProperty -Path Registry::"HKEY_CURRENT_USER\Control Panel\Keyboard" -Name InitialKeyboardIndicators -Value 2147483650


* The WinRM stuff:
Hint: Your gonna need PsExec from the SysInternals suite...
(Also, forgive the aliases I used here and there...)

$Computer_Name = "ComputerName" 

# WinRM test 
$EAC = $ErrorActionPreference 
$ErrorActionPreference = "SilentlyContinue" 
If (!((Test-NetConnection $Computer_Name).PingSucceeded)) {Write-Host "   $Computer_Name is unreachable..."; break
    $TestCommand = $null; $TestCommand = Test-WSMan -ComputerName $Computer_Name 
    If (!($TestCommand)){ 
    Write-Host " Enabling WinRM... " -No 
    C:\SysInternals\PsExec.exe -s -nobanner \\$Computer_Name /accepteula cmd /c "c:\windows\system32\winrm.cmd quickconfig -quiet" | Out-Null 
    $TestCommand = $null; $TestCommand = Test-WSMan -ComputerName $Computer_Name 
    If (!$TestCommand){Write-Host "Windows Remote Managment (WinRM) did not enable... Can't run this - EXITING." -Fore Yellow -Back DarkMagenta; Break
    }

If ($TestCommand){ Write-Host "  WinRM enabled." -Fore Yellow -Back 2
$ErrorActionPreference = $EAC 
# END WinRM test