Learn about Windows PowerShell
Summary: Microsoft Scripting Guy, Ed Wilson, talks using Windows PowerShell to enable and disable network adapters.
Microsoft Scripting Guy, Ed Wilson, is here. Today I have spent much of the day working with the various speakers who will be speaking at Windows PowerShell Saturday #007 in Charlotte, North Carolina. We have finalized the schedule. Woo Hoo!! The speaker list was set over a month ago, but certain speakers want to speak in the morning or in the afternoon. Some have more than one session and want to speak back-to-back, or not back-to-back. Others want to be opposite someone else so they can attend a specific session. (We have some awesome sessions with great Windows PowerShell speakers!) These are the sort of details that take a lot of time to completely work out. But the schedule is now set. Incidentally, the Scripting Wife was instrumental in getting the schedule worked out. She is great at these types of detailed operations.
Note PowerShell Saturday #007 will be held in Charlotte, North Carolina on February 8, 2014. This will be an awesome chance to meet and to learn from some of the best PowerShellers around. In fact, five of the speakers are also speakers at the PowerShell Summit this year. There are a limited number of tickets still available for this event, so you’ll want to sign up now. The Scripting Wife wrote a great post that provides a quick overview of the event: Psst...Charlotte PowerShell Saturday Details Leaked.
Anyway, I want to get back to talking about working with network adapters…
Note This is the second post in a series that examines working with network adapters. You may want to refer to yesterday's post, Use PowerShell to Identify Network Adapter Characteristics before you read today's.
The most fundamental things that I do with a network adapter are enable it or disable it. In fact, I perform these tasks several times a week. This is because my primary work device is a laptop and it has built-in wireless network adapters. Not surprisingly, all modern laptops have wired and wireless connections available.
When I am at home in my office, I want to have my laptop use the gigabit Ethernet switch that I have, and not go through the significantly slower wireless adapter. If I am on the road, I want to know if my wireless network adapter is enabled, and I want to control whether it connects to for example, a network named Starbucks. If I do not control such a thing, my laptop will automatically connect to every wireless it has seen before. This is why I wrote this blog post: Use PowerShell to Manage Auto-Connect Wireless Networks. Chris Wu, a Microsoft PFE also wrote this post, which takes a different approach and is a good read as well: Use PowerShell to Manage Windows Network Locations.
Before Windows Vista and Windows Server 2008, when I needed to enable or disable a network adapter, I would actually use Devcon. Devcon is a command-line tool that provides the ability to enable and disable various hardware devices. It is billed as a command-line device manager. Here is a VBScript script that I wrote to enable and disable the network interface adapter by using Devcon. Keep in mind that Devcon is not installed by default, and it must be installed prior to use.
' VBScript: AUTHOR: Ed Wilson , MS, 5/5/2004
' NAME: <turnONoffNet.vbs>
' COMMENT: Key concepts are listed below:
'1.uses the c:\devcon utility to turn on or off net
'2.uses a vbyesNO msgBOX to solicit input
'3. KB 311272 talks about devcon and shows where to get
Dim message, msgTitle
message = "Turn On Wireless? Loop is disabled" & vbcrlf & "if not, then wireless is disabled and loop enabled"
msgTitle = "change Network settings"
onWireLess = " PCMCIA\Dell-0156-0002"
onLoopBack = " *loop"
turnON = "enable"
turnOFF = "disable"
Const yes = 6
Set objShell = CreateObject("wscript.shell")
yesNO = MsgBox(message,vbyesNO,msgTitle)
If yesNO = yes Then
WScript.Echo "yes chosen"
Set objExec = objShell.exec("cmd /c c:\devcon " & turnON & onWireLess)
Set objExec = objShell.exec("cmd /c c:\devcon " & turnOFF & onLoopBack)
WScript.Echo "no chosen"
Set objExec = objShell.exec("cmd /c c:\devcon " & turnOFF & onWireLess)
Set objExec = objShell.exec("cmd /c c:\devcon " & turnON & onLoopBack)
Do until objExec.StdOut.AtEndOfStream
strText = objExec.StdOut.ReadLine()
In Windows Vista and Windows Server 2008, the Win32_NetworkAdapter class gained two methods: Disable and Enable. These methods are instance methods, which means that to use them, I need to first obtain an instance of the WMI class.
What does this mean? Well, I am using Win32_NetworkAdapter, and therefore I am working with network adapters. So, I need to get a specific network adapter, and then I can disable it or enable it. Here is how it might work:
$wmi = Get-WmiObject -Class Win32_NetworkAdapter -filter "Name LIKE '%Wireless%'"
Keep in mind that when calling a method in Windows PowerShell, the parenthesis are required.
If I need to specify alternate credentials, I can specify a remote computer name and an account that has local admin rights on the remote box. The script would appear like the following:
$wmi = Get-WmiObject -Class Win32_NetworkAdapter -filter "Name LIKE '%Wireless%'" –credential (Get-Credential) –computername remotecomputer
Keep in mind that WMI does not permit alternate credentials for a local connection. Attempts to use alternate credentials for a local connection results in the following error:
PS C:\> gwmi win32_networkadapter -Credential (Get-Credential)
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
gwmi : User credentials cannot be used for local connections
At line:1 char:1
+ gwmi win32_networkadapter -Credential (Get-Credential)
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Comman
For local connections, this error is not a Windows PowerShell issue. WMI has always behaved in this manner, even going back to the VBScript days.
In Windows 8.1 and Windows 8, I can use Windows PowerShell to stop or to start a network adapter by using one of the CIM commands. Of course, the function wraps the WMI class, but it also makes things really easy. The NetAdapter functions are shown here (gcm is an alias for the Get-Command cmdlet):
PS C:\> gcm -Noun netadapter | select name, modulename
Note To enable or to disable network adapters requires admin rights. Therefore you must start the Windows PowerShell console with an account that has the proper rights to perform the task.
The various network adapters on my laptop appear in the image that follows.
I do not like having enabled, disconnected network adapters. Instead, I prefer to only enable the network adapter I am using. There are a number of reasons for this, such as simplified routing tables, performance issues, and security concerns. In the past, I wrote a script. Now I only need to use a Windows PowerShell command. If I want to disable only the non-connected network adapters, the command is easy:
Get-NetAdapter | ? status -ne up | Disable-NetAdapter
The problem with the previous command is that it prompts. This is not much fun when there are multiple network adapters to disable. The prompt is shown here:
To suppress the prompt, I need to supply $false to the –confirm parameter, as shown here:
Get-NetAdapter | ? status -ne up | Disable-NetAdapter -Confirm:$false
A quick check in Control Panel shows that the disconnected adapters are now disabled:
If I want to enable a specific network adapter, I use the Enable-Network adapter cmdlet. I can specify by name as shown here:
Enable-NetAdapter -Name ethernet -Confirm:$false
If I do not want to type the adapter name, I can use the Get-NetAdapter cmdlet to retrieve a specific network adapter and then enable it, as shown here:
Get-NetAdapter -Name vethernet* | ? status -eq disabled | Enable-NetAdapter -Confirm:$false
It is also possible to use wildcard characters with the Get-NetAdapter to retrieve multiple adapters and pipe them directly to the Disable-NetAdapter cmdlet. The following command permits the confirmation prompts so that I can selectively enable or disable the adapter as I wish:
PS C:\> Get-NetAdapter -Name vethernet* | Disable-NetAdapter
Are you sure you want to perform this action?
Disable-NetAdapter 'vEthernet (InternalSwitch)'
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):y
Disable-NetAdapter 'vEthernet (ExternalSwitch)'
(default is "Y"):n
Network Adapter Week will continue tomorrow when I will talk about renaming network adapters.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at email@example.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
Hi Ed, I am posting a comment here as I no longer have your email address.
Couple of points to note
1. Get-WmiObject is so old and outdated. Use Get-CimInstance
2. Win32_NetworkAdapter is deprecated.
Somehow this notion of getting data from WMI vs using Net Cmdlets is misleading. Net cmdlets also invoke WMI providers - they are just wrappers over WMI classes.
@Osama Sajid I am not trying to show an either or, but what I am trying to do is to show different ways of accomplishing the same thing. Unfortunately, the CIM cmdlets are only available on PowerShell 3 and above. The NetAdapter module must have Windows 8 or above. Lots of our customers are still using older versions of PowerShell and of the operating system. FYI, when I look up Win32_NetworkAdapter WMI class, it does not have a deprecated tag. Email me at Scripter@Microsoft.com
@Ed - I'm getting a permissions error when I try to use this on Windows 8.1 PermissionDenied: (MSFT_NetAdapter...e = "HOSTNAME"):ROOT/StandardCimv2/MSFT_NetAdapter) [Disable-NetAdapter], CimException I am an administrative user and should have the proper
rights to run this. Any ideas? Thanks!
FYI: I recently needed to enable a couple of NICs on a Hyper-V 2012 R2 server and was getting nowhere with Enable-NetAdapter in Powershell. The command would appear to work, i.e. no errors were returned, but the adapters stayed steadfastly disabled. I
ended up using the WMI commands and they worked first time. Go figure.