Skip to content

Instantly share code, notes, and snippets.

@bashenk
Last active December 22, 2020 21:05
Show Gist options
  • Save bashenk/27294460c50c503707abeb9e76aa7125 to your computer and use it in GitHub Desktop.
Save bashenk/27294460c50c503707abeb9e76aa7125 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Add a Wi-Fi network profile to the wlan table
#>
Function Add-WifiNetwork {
[CmdletBinding(DefaultParameterSetName='PassPhrase')]
Param(
## The name of a wireless LAN profile, as well as the SSID of the wireless LAN.
[Parameter(Position=0,Mandatory=$true)]
[String]$SSIDName,
## The hex (SSID) element contains the SSID of a wireless LAN in hexadecimal format.
##
## Although the hex and name elements are optional, at least one hex or name element must appear as a child of the SSID element.
##
## When profile information is converted to an SSID, the hex element is converted to the SSID (if present) and the name element is ignored. If the hex element is not present, the name element is converted to an SSID using Unicode to ASCII conversion.
##
## When an SSID is stored in a profile, the hex element is always generated. The name element is only generated if the both the ASCII to Unicode conversion of the SSID and the XML profile generation are successful. Some information from the original SSID may be lost when it is converted to a name.
[Parameter()]
[String]$SSIDHex,
## The passhprase for the network connection.
## If the protected element has a value of TRUE, then this key material is encrypted; otherwise, the key material is unencrypted. Encrypted key material is expressed in hexadecimal form.
[Parameter(Position=1,Mandatory=$true,ParameterSetName='PassPhrase')]
[String]$Passphrase,
## The network key for the network connection.
## If the protected element has a value of TRUE, then this key material is encrypted; otherwise, the key material is unencrypted. Encrypted key material is expressed in hexadecimal form.
[Parameter(Position=1,Mandatory=$true,ParameterSetName='NetworkKey')]
[String]$PreSharedKey,
## Specifies which key index should be used to encrypt wireless traffic. This is only used when keyType is set to "networkKey".
[Parameter(Position=2,Mandatory=$true,ParameterSetName='NetworkKey')]
[ValidateSet(0,1,2,3)]
[String]$KeyIndex,
## Indicates whether a shared key is encrypted.
##
## For Windows Vista and Windows Server 2008, protected always has a value of TRUE if the profile was retrieved from the profile store (for example, by calling WlanGetProfile).
##
## For profiles intended for use on Windows XP with Service Pack 3 (SP3) or Wireless LAN API for Windows XP with Service Pack 2 (SP2), protected must have a value of FALSE.
[Parameter()]
[Bool]$KeyIsEncrypted=$false,
## Specifies the authentication method that must be used to connect to the wireless LAN.
[Parameter()]
[ValidateSet('open','shared','WPA','WPAPSK','WPA2','WPA2PSK')]
[String]$Authentication='WPA2',
## Sets the data encryption to use to connect to the wireless LAN.
##
## When the encryption element has a value of WEP, keyType must be set to networkKey.
##
## The AES encryption method is as specified in the 802.1X and 802.11i specifications.
[Parameter()]
[ValidateSet('none','WEP','TKIP','AES')]
[String]$Encryption='AES',
## Whether 802.1X authentication is used
[Parameter()]
[Bool]$UseOneX=$false,
## The connectionType (WLANProfile) element indicates the operating mode of the network.
##
## A value of ESS indicates an infrastructure network, while IBSS indicates an ad-hoc network.
[Parameter()]
[ValidateSet('IBSS','ESS')]
[String]$ConnectionType='ESS',
## The connectionMode (WLANProfile) element indicates whether connection to a wireless LAN should be automatic or initiated by user.
##
## If connectionType is set to ESS, this value can be either auto or manual. The default value is auto if this element is absent.
## If connectionType is set to IBSS, this value must be manual.
##
## auto — The connection to the wireless network should be initiated automatically whenever the network is in range.
## manual — The connection to the wireless network is only initated upon the explicit request of a user.
[Parameter()]
[ValidateSet('auto','manual')]
[String]$ConnectionMode='auto',
## Whether to randomize the MAC address that is used to connect to a network.
##
## If enabled, the randomized MAC address is calculated as follows:
## addr = SHA-256(SSID,macaddr,connId,secret)
##
## The abbreviations above correspond to the following descriptions:
## — SSID —
## The name of the network
##
## — macaddr —
## The original MAC address
##
## — connId —
## A parameter that changes if the user removes (and re-adds) the network to its preferred network list.
##
## — secret —
## A 256-bits cryptographic random number generated during system initialization, unique per interface, and kept the same across reboots. Bits in the most significant byte of addr are set so it becomes a locally administered, unicast address. This hash construction is similar to the generation of IPv6 interface identifiers as proposed in RFC 7217. It assures that systems relying on fixed MAC addresses continue to work as expected, e.g., when authentication is performed based on the MAC address.
[Parameter()]
[Bool]$EnableMACRandomization=$false
)
if ($PSCmdlet.ParameterSetName -like 'PassPhrase') {
$keyMaterial=$Passphrase
$keyType='passPhrase'
} elseif ($PSCmdlet.ParameterSetName -like 'NetworkKey') {
$keyMaterial=$PreSharedKey
$keyType='networkKey'
}
[System.XML.XMLDocument]$xml=@"
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>$SSIDName</name>
<SSIDConfig>
<SSID>
<name>$SSIDName</name>
</SSID>
</SSIDConfig>
<connectionType>$ConnectionType</connectionType>
<connectionMode>$ConnectionMode</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>$Authentication</authentication>
<encryption>$Encryption</encryption>
<useOneX>$(([String]$UseOneX).ToLower())</useOneX>
</authEncryption>
<sharedKey>
<keyType>$KeyType</keyType>
<protected>$(([String]$KeyIsEncrypted).ToLower())</protected>
<keyMaterial>$keyMaterial</keyMaterial>
</sharedKey>
</security>
</MSM>
<MacRandomization xmlns="http://www.microsoft.com/networking/WLAN/profile/v3">
<enableRandomization>$EnableMACRandomization</enableRandomization>
</MacRandomization>
</WLANProfile>
"@
try {
$tmpFile=New-TemporaryFile
$tempFile=$tmpFile|Rename-Item -NewName {$_ -replace 'tmp$','xml'} -PassThru;
} catch {
Remove-Item $tmpFile -Force 2>$null
Remove-Item $tempFile -Force 2>$null
throw "Failed to create temporary file."
}
try {
if ($PSBoundParameters.ContainsKey('SSIDHex')) {
$ns=New-Object System.Xml.XmlNamespaceManager($xml.NameTable);
$ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI);
$xml.SelectSingleNode("//ns:WLANProfile/ns:SSIDConfig/ns:SSID",$ns).PrependChild($xml.CreateElement("hex",$xml.DocumentElement.NamespaceURI)).InnerText=$SSIDHex;
}
$xml.Save($tempFile.FullName)
Start-Process cmd -Verb RunAs -ArgumentList "/c NETSH wlan add profile filename=$($tempFile.FullName)"
} finally {
Remove-Item $tmpFile -Force 2>$null
Remove-Item $tempFile -Force 2>$null
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment