Create your own Wifi-hotspot Windows 7 / Windows 8

The topic of making your Windows box a wireless AP, and then sharing internet connection with your wireless devices connected, is not something new, but I’ve never seen anyone wrap Powershell around it. Also this script is designed to work on Windows 7, will work under Windows 8, but with windows 8 and Powershell v. 3.0 some parts will be easier to script. There are 3 parts to creating your personal Wifi-Hotspot:

First allow Windows to control the power state of your Wireless Card. You can either do this from the GUI, or if you’re a geek, you might be looking to do this via Powershell, which is what I’ve done.

Second Enable the HostedNetwork feature available in Windows 7. Again, the technical bits of how this works, and what hosted network can do, is available from Microsoft, here. Good part about the hosted network is that is comes with its own DHCP, so Internet Access will pretty much work out of the box.

Finally Enable Internet Connection Sharing (ICS) – as much as I would like to automate this in Powershell, this just isn’t possible in Windows 7 (I’ll dig inside Windows 8, see if it can be done there). To enable ICS,  follow these Instructions from Microsoft.

The Script

To wrap Steps 1 and 2 up I’ve written a Powershell script that will enable what is needed automatically (so you still have to enable ICS by hand, but that’s easy). Click the link to download Enable-Wifi-HotSpot. You must run this script from an elevated powershell console, it won’t fully work unless you do.

Read on to get some learning points on how I did this.

CAUTION: If you just run the script out of the box, please read the instructions it spits out (it has some commands to temporarily disable your Wifi, so if you are on a wifi only connection you will get disconnected)

Learning Points

First step says….

Enable_TurnOff

I wanted to tick the “Allow the computer to turn off this device to save power” check box programatically. This tick box corresponds to the following registry key:

HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\<ID>\PnpCapabilities

<ID> is a device ID given by Windows to the network adapter when it is installed. When the tick box is checked the first bit of the DWORD value of PNPCapabilities is 0. If the tick box is unchecked the first bit becomes 8.

PNP-capabilities

Also this value is not accepted automatically by the OS, after changing it, you have to reboot (so the Internet says)…but I just went with disabling and enabling the WLAN Adapter and it worked for me. I figured if changing the setting works from the Windows GUI with no reboot there was a way around rebooting.

So our first order of business is to find that <ID> parameter that maps each Wifi adapter to the registry keys. I had the script find all possible Wifi adapters on the system:

$WifiAdapters = Get-WmiObject -Namespace root\wmi -Class MSNdis_PhysicalMediumType -Filter `
 "(NdisPhysicalMediumType=1 OR NdisPhysicalMediumType=8 OR NdisPhysicalMediumType=9) AND NOT InstanceName LIKE '%virtual%'"

I also included integer values for NDISSPhysicalMediumType are included at the top of the script. For reference they can be obtained from 2 places:

  • Windows SDK or WDK (more info here).
  • You can cheat a little and run this command on a Windows 8/ Windows 2012
(Get-NetAdapter | Get-Member PhysicalMediaType).Definition

Once  we have the list of all Wifi adapters, we take each adapter and see if its configuration is OK and it is not disabled. I’m using a filter on the ConfigManagerErrorCode property.  The possible values for this property can be found here.

$PhysicalAdapter = Get-WmiObject -Class Win32_NetworkAdapter -Filter "Name='$($WifiAdapter.InstanceName)'" -Property * |`
 ? {$_.ConfigManagerErrorCode -eq 0 -and $_.ConfigManagerErrorCode -ne 22}

The ID parameter we are looking for is stored in “$PhysicalAdapter.DeviceID” but unfortunately it is not stored in the format we need, (in my case DeviceID = 15, and I needed to transform into 0015). I did it with this line:

$AdapterDeviceNumber = $("{0:D4}" -f [int]$($PhysicalAdapter.DeviceID))

From here on, things get a little simpler. once you get the registry key, I just check if the last HEX digit is 0 or 8.

$PnPCapabilitiesValue = (Get-ItemProperty -Path $KeyPath).PnPCapabilities
 #convert decimal string to HEX to compare first bit
 $PNPCapHEX = [convert]::tostring($PnPCapabilitiesValue,16)

I compare the PNPCapHEX value to see what the first digit is,and decide to just do a “disable/enable” of the wifi adapter, or change the value and then “disable/enable”. Disabling the NIC can be done easily once you have the network adapter object.

$PhysicalAdapter.Disable() | out-null
 $PhysicalAdapter.Enable() | out-null

Note that the commands above return no output. If you take out the out-null, you should see return value = 0. If you get “return value = 5” that is an access denied, and it means you didn’t run the script from an elevated prompt.

Now the registry settings are done, all that is left is to build the netsh command to enable the hosted network. What is “of interest, in this section” is how we read out the wifi password ( I wanted the script to be a little secure, and then how we pass the wifi password to the netsh (that involves converting from secure string to plaintext). For this last conversion I used the function described here.

#now that WiFi adapter is configured, let's add our hotspot
$WifiPassSec = Read-host -Prompt "Enter password for your Wifi, must be at least 8 chars long, complex" -AsSecureString
#enable hosted network
$WifiPass = ConvertFrom-SecureToPlain $WifiPassSec
$SetupHN = "netsh wlan set hostednetwork mode=allow ssid=Rivnet-Wifi key=`"$WifiPass`" keyUsage=persistent`nnetsh wlan start hostednetwork"
Invoke-expression $SetupHN
$SetupHN = $null
$WifiPass = $null

So now you should be all set, just connect your devices to the Wifi and enjoy Internet access via your laptop. Finally, you might want to turn off the hosted network at some time. To do this, run this command:

netsh wlan stop hostednetwork

netsh wlan set hostednetwork mode=disallow

Hopefully this will  help someone out there, looking for a scripted way to do this. For me it was quite a learning journey, since I got to dig inside windows’s internals while scripting this.


Print pagePDF pageEmail page
Bookmark the permalink.

One Response to Create your own Wifi-hotspot Windows 7 / Windows 8

  1. netro says:

    Hey thanks for the script it really works. I was not able to run it on power shell. it gave error like power shell is disabled. I can run it with ‘ powershell -ExecutionPolicy ByPass -File script.ps1 ‘

    Thanks for help