Category Archives: Powershell

PS Script: Form to get MAC Address (v1.0)

Description: Enter the name of a computer and get it’s MAC address. The form is still a work in progress, with some of the functions and results needing tightened up and the form is ugly. Remember if you copy and paste this text I often find the format of the quotation marks gets changed so the script becomes corrupt.

Code:

#region start declare .NET FUNCTIONALITY
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
Add-Type -AssemblyName System.Windows.Forms
[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.VisualBasic’) | Out-Null
$psexec = ‘\\<computer name>\share$\PSTools\PsExec.exe’
#endregion end declare .NET FUNCTIONALITY

#region FUNCTIONS

#region FUNCTION #0 Get computer MAC from ARP table – not used in this script
Function arpcheck () {
$IP = [System.Net.Dns]::GetHostByName($computer).AddressList[0].IpAddressToString #the IP of the computer I need to get the MAC for.
$mac = arp -a
($mac | ? { $_ -match $ip } ) -match “([0-9A-F]{2}([:-][0-9A-F]{2}){5})” | out-null;

if ( $matches ) {

$matches[0];

} else {

“Not Found”

}
}
#endregion FUNCTION #0 Get computer MAC from ARP table

#region FUNCTION #1 Display Form
Function showform () {
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
}
#endregion FUNCTION #1 Display Form

#region FUNCTION #2 Conversion and Display

function get-mac2 ()
{
$computer = $ECN.text

#test if WinRM is enabled on the remote computer, this script requires WinRM is enabled.
$winrm = test-wsman -ComputerName $computer -ErrorAction SilentlyContinue
if ($winrm)
{

$VPNTC = Test-Connection $computer -Count 1 -ErrorAction SilentlyContinue
$VPNIP = ($VPNTC.IPV4Address).IPAddressToString
If ($VPNIP -match “92.*”){$MAC.text=”ERROR:VPN Reply”} #a test/result if I’m on my VPN and the computer is offline, an active ping response is still returned by the VPN starting with 92.
Else
{
$TC = Test-Connection -count 1 $computer -Quiet
# If the PC is online then get the InterfaceIndex ID of the active NIC
If ($TC -eq “True”){
$result1 = Invoke-Command -ComputerName $computer {(get-wmiobject win32_networkadapter -filter “netconnectionstatus = 2″).InterfaceIndex | out-string}
$result1 = $result1.Trim()
# If multiple NICs are active then this script won’t work – it still a work in progress 🙂
If ($result1.length -lt 3) {
$result2 = Invoke-Command -ComputerName $computer {(gwmi Win32_NetworkAdapter | where {$_.InterfaceIndex -eq $using:result1}).MACAddress}
$MAC.text=$result2
}
Else {$MAC.text=”ERROR:Multi MACs”}
}
Else {$MAC.text=”ERROR:PC Offline”}
}
}
Else {$MAC.text= “WinRM Disabled”}
}
#endregion FUNCTION #2 Conversion and Display

#region FUNCTION #3 Copy to clipboard
Function ClipMe() {
[System.Windows.Forms.Clipboard]::SetText($MAC.Text.Trim())
}
#endregion FUNCTION Copy to clipboard

#endregion FUNCTIONS

#region FORM

#region FORM ELEMENT #1 THE BASIC FORM
$Form = New-Object System.Windows.Forms.Form
$form.text = “MAC Address Finder”
$Form.Size = New-Object System.Drawing.Size(400,300)
$Form.Font = “Segoe UI,12”
$Form.ForeColor = [System.Drawing.Color]::White
$Form.BackColor = [System.Drawing.Color]::LightSteelBlue
#endregion FORM ELEMENT #1 The basic form

#region FORM ELEMENT #2 GROUP BOXES

$groupConvert = New-Object System.Windows.Forms.GroupBox
$groupConvert.Location = New-Object System.Drawing.Size(10,20)
$groupConvert.size = New-Object System.Drawing.Size(360,170)
$groupConvert.text = “Enter Computer Name:”
$Form.Controls.Add($groupConvert)
#endregion FORM ELEMENT #2 group boxes

#region FORM ELEMENT #3 LABELS and TEXTBOXES

$cnlabel = New-Object System.Windows.Forms.Label
$cnlabel.Text = “Enter Computer Name:”
$cnlabel.AutoSize = $True
$cnlabel.Font = “Segoe UI,16”
$cnlabel.Location = “20,20”
$groupConvert.Controls.Add($cnlabel)

$ECN = New-Object System.Windows.Forms.Textbox
$ECN.Size = New-Object System.Drawing.Size(135,100)
$ECN.Font = “Segoe UI,16”
$ECN.Location = “20,60”
$ECN.TextAlign = “Center”
$groupConvert.Controls.Add($ECN)

$malabel = New-Object System.Windows.Forms.Label
$malabel.Text = “MAC Address:”
$malabel.AutoSize = $True
$malabel.Font = “Segoe UI,16”
$malabel.Location = “20,120”
$groupConvert.Controls.Add($malabel)

$MAC = New-Object System.Windows.Forms.Textbox
$MAC.Size = New-Object System.Drawing.Size(185,100)
$MAC.ReadOnly = $true
$MAC.Font = “Segoe UI,16”
$MAC.Location = “170,120”
$MAC.TextAlign = “Center”
$groupConvert.Controls.Add($MAC)

#endregion LABELS and TEXTBOXES

#region FORM ELEMENT #4 BUTTONS

#region BUTTON #1 Create Convert button
$ConvertButton = New-Object System.Windows.Forms.Button
$ConvertButton.Location = New-Object System.Drawing.Size(20,200)
$ConvertButton.Size = New-Object System.Drawing.Size(80,40)
$ConvertButton.Text = “Get MAC”
$ConvertButton.Font = “Segoe UI,12″
$ConvertButton.BackColor = [System.Drawing.Color]::Green
$ConvertButton.Enabled = $True
$ConvertButton.Add_Click(
{
$MAC.text=”Pending…”
get-mac2
$Closebutton.Text = “Exit”
$buttonCopyToClipboard.Enabled = $true
})
$Form.Controls.Add($ConvertButton)
#endregion BUTTON #1 Create Convert button

#region BUTTON #2 Create CANCEL button
$Closebutton = New-Object System.Windows.Forms.button
$Closebutton.Location = New-Object System.Drawing.Size(280,200)
$Closebutton.Size = New-Object System.Drawing.Size(80,40)
$Closebutton.Text = “Cancel”
$Closebutton.Add_Click(
{
$form.Close()
})
$Form.Controls.Add($Closebutton)
#endregion BUTTON #2 Create CANCEL button

#region BUTTON #3 Create CLIPBOARD button
$buttonCopyToClipboard = New-Object System.Windows.Forms.Button
$buttonCopyToClipboard.Location = New-Object System.Drawing.Size(110,200)
$buttonCopyToClipboard.Size = New-Object System.Drawing.Size(160,40)
$buttonCopyToClipboard.Text = “Copy to clipboard”
#$buttonCopyToClipboard.Font = “Segoe UI,12”
$buttonCopyToClipboard.Enabled = $False
$buttonCopyToClipboard.Add_Click(
{
#call the function Clipme to copy the MAC address to the system clipboard
ClipMe
})
$Form.Controls.Add($buttonCopyToClipboard)
#endregion BUTTON #3 Create CLIPBOARD button

#region BUTTON #4 Create Clear button
$Clearbutton = New-Object System.Windows.Forms.button
$Clearbutton.Location = New-Object System.Drawing.Size(180,59)
$Clearbutton.Size = New-Object System.Drawing.Size(80,40)
$Clearbutton.Text = “Clear”
$Clearbutton.Add_Click(
{
$buttonCopyToClipboard.Enabled = $False
#clears the text from both fields
$ECN.text=””
$MAC.text=””
})
$groupConvert.Controls.Add($Clearbutton)
#endregion BUTTON #4 Create CLEAR button

#endregion BUTTONS

#endregion FORM

#region SHOW FORM
showform
#endregion SHOW FORM

PS Tip – Use local variable in Invoke-Command (remote computer)

I have a locally declared variable $var1

Using it directly doesn’t work, the value of the variable is not carried over within the invoke-command scriptblock.

$result2 = Invoke-Command -ComputerName $computer {(gwmi Win32_NetworkAdapter | where {$_.InterfaceIndex -eq $var1}).MACAddress}

Instead you have to use the “Using” scope modifier followed by a colon, thus $var1 becomes $using:var1

$result2 = Invoke-Command -ComputerName $computer {(gwmi Win32_NetworkAdapter | where {$_.InterfaceIndex -eq $using:var1}).MACAddress}

PS Function – Copy contents of form textbox to clipboard

#region FUNCTION #3 Copy to clipboard
Function ClipMe() {
[System.Windows.Forms.Clipboard]::SetText($ST.Text.Trim())
}
#endregion FUNCTION Copy to clipboard

NB: In this example my form has a textbox called $ST – The function captures the text content and trims it to remove any unwanted white space.

$ST = New-Object System.Windows.Forms.Textbox
$ST.Size = New-Object System.Drawing.Size(135,100)
$ST.ReadOnly = $true
$ST.Font = “Segoe UI,16”
$ST.Location = “150,120”
$ST.TextAlign = “Center”
$groupConvert.Controls.Add($ST)

Script: Close form after certain time

I use this to create time-limited splash screens I then display during various other scripts I run to keep the end user informed. The beauty of this one is that is there is no DialogResult i.e OK, Yes or Cancel when the form is closed, therefore no annoying pop-up messages when the script is run in GUI-only mode (text corrected 09/05/17).
function Splash1 {
[System.Windows.forms.Application]::EnableVisualStyles()
$form1 = New-Object ‘System.Windows.forms.form’
$label1 = New-Object ‘System.Windows.Forms.Label’
$timer1 = New-Object ‘System.Windows.Forms.Timer’
$InitialFormWindowState = New-Object ‘System.Windows.Forms.FormWindowState’
$form1_Load = {
$TotalTime = 5 #in seconds
$script:StartTime = (Get-Date).AddSeconds($TotalTime)
#Start the timer
$timer1.Start()
}
$timer1_Tick={
#Use Get-Date for Time Accuracy
[TimeSpan]$span = $script:StartTime – (Get-Date)
#Update the display
if ($span.TotalSeconds -le 0) {
$timer1.Stop()
$form1.Close()
}
}
$Form_StateCorrection_Load=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed=
{
#Remove all event handlers from the controls
try
{
$form1.remove_Load($form1_Load)
$timer1.remove_Tick($timer1_Tick)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
}
catch [Exception]
{ }
}
$form1.SuspendLayout()
#
# form1
#
$form1.ControlBox = $false
$form1.StartPosition = “CenterScreen”
$form1.text = “BitLocker Installation”
$form1.Size = New-Object System.Drawing.Size(300,100)
$form1.Font = “Segoe UI,12”
$form1.Topmost = $True
$form1.ForeColor = [System.Drawing.Color]::White
$form1.BackColor = [System.Drawing.Color]::LightSteelBlue
$form1.add_Load($form1_Load)
#
# label1
#
$label1.Text = “Checking System…”
$label1.AutoSize = $True
$label1.Font = “Segoe UI,18”
$label1.Location = “42,15”
$form1.Controls.Add($label1)
#
# timer1
#
$timer1.add_Tick($timer1_Tick)
$form1.ResumeLayout()
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
}
#display form
Splash1| Out-Null
PS – Not my own work, I amended a script I found on the web, I just can’t remember where I found it. If I find the link I’ll post it here. Credit where credit’s due after all…

Get Hyper-V host name from guest VM

The Problem
I have a server that I know is a VM but I do not know what Hyper-V host it is on.

The Solution
Open an elevated PowerShell prompts on the guest VM and enter the following:

(get-item “HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters”).GetValue(“HostName”)

The Hyper-V host name will be returned

NB: please be careful when pasting lines that have quotation marks into PowerShell and notepad, then into PowerShell. I’ve found the format of the quotation mark is not recognised and causes the command to fail. If in doubt, manually replace the quotation marks.

Disclaimer: provided “AS IS” with no warranties and confer no rights