I'm trying to write a script that requires turning off the Internet entirely and then turning it back on. I'd like it to work in as many cases as possible...
support for Window 7 and up
if multiple Internet connections are on (like WiFi and LAN)
regardless of how these connections are named
limited user account, UAC?
ipconfig /release and ipconfig /renew, as suggested in this answer, do not work with 2 internet connections. /release disables the active connection (say WLAN) but the computer falls back on the LAN connection and you're still online.
$connectedAdapters = Get-WmiObject -Class Win32_NetworkAdapter -Filter "NetConnectionStatus = 2"
$connectedAdapters | Invoke-WmiMethod -Name disable
My questions are:
Is NetConnectionStatus = 2 a reliable proxy for internet access, and is it available on Windows 7 and up, regardless of the brand of your NIC?
Is this compatible with a limited user account with UAC on? I think so...
On my machine this query also catches VirtualBox Host-Only Ethernet Adapter. Is it a problem if I disable/enable it too?
Are Get-WmiObject and Invoke-WmiMethod are available on Windows 7 and up, right?
The questions are not entirely settled, but I've developed a script that works:
PowerShell Internet Connection helper functions: Go-Offline, Go-Online, Test-InternetAccess
#Requires -Version 2.0
function Test-InternetAccess {
<#
.SYNOPSIS
Tests connectivity by pinging Google DNS servers once
.DESCRIPTION
Uses Test-Connection to ping a host, with -Quiet for returning a boolean. The default is a highly available Google DNS server (8.8.4.4)
.EXAMPLE
Test-InternetAccess
.EXAMPLE
Test-InternetAccess example.com
.INPUTS
None.
.OUTPUTS
Boolean
#>
param (
[String]
$RemoteHost = "google-public-dns-b.google.com"
)
Test-Connection -Computer $RemoteHost -BufferSize 16 -Count 1 -Quiet
}
function Go-Offline {
<#
.SYNOPSIS
Disables your internet connection
.DESCRIPTION
Finds all network adapters that appear connected and disables them, taking you offline. Later on you can re-enable just those adapters, because they've been stored in an XML file. Connected adapters are detected through WMI. A NetConnectionStatus value of 2 means Connected. 7 means Media Disconnected.
.EXAMPLE
Go-Offline
.INPUTS
None.
.OUTPUTS
None.
.LINK
https://blogs.technet.microsoft.com/heyscriptingguy/2011/10/07/use-powershell-to-identify-your-real-network-adapter/
.LINK
https://msdn.microsoft.com/en-us/library/aa394216(v=vs.85).aspx
#>
[CmdletBinding(SupportsShouldProcess=$True)]
param()
$XMLLocation = "$env:TEMP\Disabled-NICs.xml"
if (Test-InternetAccess) {
$connectedAdapters = Get-WmiObject -Class Win32_NetworkAdapter -Filter "NetConnectionStatus = 2"
# Go offline
$connectedAdapters | Invoke-WMIMethod -Name disable 1>$null
# Save which adapters were connected at the time
$connectedAdapters | Select Name, DeviceID | Export-Clixml -Path $XMLLocation -Force
Write-Output "You've been taken offline!"
Sleep 1
} else {
Write-Output "Connection already down..."
Sleep 1
}
}
function Go-Online {
<#
.SYNOPSIS
Re-enables your internet connection
.DESCRIPTION
Finds all network adapters that were previously disabled by Go-Offline and enables them. This information is persisted in a temp file.
.EXAMPLE
Go-Online
.INPUTS
None.
.OUTPUTS
None.
.LINK
https://blogs.technet.microsoft.com/heyscriptingguy/2011/10/07/use-powershell-to-identify-your-real-network-adapter/
#>
[CmdletBinding(SupportsShouldProcess=$True)]
param()
$XMLLocation = "$env:TEMP\Disabled-NICs.xml"
if (!(Test-InternetAccess)) {
# Get the NICs that have been previously disabled
$connectedAdapters = Import-Clixml "$env:TEMP\Disabled-NICs.xml" | Select -ExpandProperty DeviceID | ForEach {Get-WMIObject -Class Win32_NetworkAdapter -Filter "DeviceID = $_"}
# Get back online
$connectedAdapters | Invoke-WMIMethod -Name enable | Out-Null
Write-Output "Internet access restored!" # Triggers early, before actual re-connection
Sleep 1
}
}
Tested on Windows 7.
Related
I got a client who asked me to find all of his Dhcp and DNS servers with some additional info like DC servers and operationsystem
so i decided to try sharpen my powershell skills but im still new to this so i wrote this script but i guess something is still missing because it doesnt work
EDIT: i managed to find a way to get the info i want which is the OS but it gets me back ALL the servers in the company
$servers = get-dhcpserverindc
foreach($server in $Servers){
get-adcomputer -filter {Operatinsytem -like "*windows server*"} -properties
Operatingsystem | sort name | format-table name,Operatinsytem
}
This is not too tricky. First off, you connect to a machine with the RSAT Tools installed, like an admin server, jump box, or Domain Controller, and get a list of all DHCP Servers.
$DHCPServers = Get-DhcpServerInDC
Then we use PowerShell's built in looping logic to step through each server, and check for the OS info you need.
ForEach ($DHCPServer in $DHCPServers){
$OSInfo = Get-CIMInstance -ComputerName $DHCPServer.DnsName -ClassName Win32_OperatingSystem
}
Finally, we'll modify this above to return the info you're looking for, namely the IP Address, Name, and OS Version
ForEach ($DHCPServer in $DHCPServers){
$OSInfo = Get-CIMInstance -ComputerName $DHCPServer.DnsName -ClassName Win32_OperatingSystem
[pscustomobject]#{
ServerName = $DHCPServer.DnsName;
IPAddress=$DHCPServer.IpAddress;
OS=$OSInfo.Caption
}
}
ServerName IPAddress OS
---------- --------- --
dc2016 192.168.10.1 Microsoft Windows Server 2016 Standard
From there, you can store it in a variable, make it a spreadsheet, do whatever you need to do.
Hope this helps.
If this isn't working, make sure you have enabled PowerShell Remoting first.
I already knew how to get all network adaptors names, but I can't tell the difference between normally using and not identified
By using
netsh interface ip show interfaces
or other commands ,you may get all adaptors names.
The necessary information can be obtained using the Win32_NetworkAdapter class.For example:
Get-CimInstance -ClassName Win32_NetworkAdapter -Filter #'
NetConnectionID = "Local Area Connection" AND
NetConnectionStatus=2 AND NetEnabled = True AND PhysicalAdapter = True
'# | Format-List *
The Get-WmiObject cmdlet can also be used, but starting in PowerShell 3.0, it has been superseded by Get-CimInstance.Starting with Windows 8, you can use the Get-NetAdapter cmdlet.
I need a way to programatically (powershell, batch, c#, ...) tell my VPN adapter that it has to register address in DNS.
There seems to be no parameter for this using PowerShell to create the VPN entry:
Powershell.exe -executionpolicy bypass -command Add-VpnConnection -AllUserConnection -Name "ProfileName" -ServerAddress "xyz.com" -TunnelType L2tp -EncryptionLevel Optional -L2tpPsk "password" -AuthenticationMethod MSChapv2 -Force
We had no success doing this by GPO, netsh or c# (DotRas -> VpnEntry.Options.RegisterIPWithDns = true;)
Thanks in advance!
As far as I know there are no way of doing it with the Add-VpnConnection command.
Instead you have to edit the Remote Access Phonebook.
If it is a -alluserconnection VPN the phonebook can be found here:
C:\ProgramData\Microsoft\Network\Connections\Pbk\rasphone.pbk
If it is a per user VPN adapter the phonebook can be found here:
C:\Users\USERNAME\AppData\Roaming\Microsoft\Network\Connections\Pbk\rasphone.pbk
Now use this Powershell command to set the setting:
$RASPhoneBook =
“C:\ProgramData\Microsoft\Network\Connections\Pbk\rasphone.pbk”
(Get-Content $RASPhoneBook) -Replace ‘IpDnsFlags=0’, ‘IpDnsFlags=3’ |
Set-Content $RASPhoneBook
“Register this connection’s addresses in DNS” is now set for your VPN adapter.
Try something like this
Get-NetIPConfiguration | where {$_.some.identifying.vpn.feature -eq 'name'} | Get-NetConnectionProfile | Set-DnsClient -RegisterThisConnectionsAddress:$True
I'd suggest using a different approach for your use case.
Example:
Using PowerShell to Get or Set NetworkAdapterConfiguration-View and Change Network Settings Including DHCP, DNS, IP Address and More (Dynamic AND Static) Step-By-Step
Following commands can be useful to configure the settings:
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName . | Select-Object -Property [a-z]* -ExcludeProperty IPX*,WINS*
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "FullDNSRegistrationEnabled=true" –ComputerName . | Get-Member
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "DomainDNSRegistrationEnabled=true" –ComputerName . | Get-Member
I want to changed an networking adapter ip address. For some security reason, we should change it when it is disabled.
I used the following:
Set-NetIPAddress -InterfaceAlias "Ethernet 3" -PrefixLength 20 -IPAddress 10.91.62.201
But that failed with following message:
Set-NetIPAddress : No matching MSFT_NetIPAddress objects found by CIM query for instances of the ROOT/StandardCimv2/MSFT_NetIPAddress class on the CIM
server: SELECT * FROM MSFT_NetIPAddress WHERE ((IPAddress LIKE '10.91.62.201')) AND ((InterfaceAlias LIKE 'Ethernet 3'))
Is there anyone who know how to changed a disabed networking adapter configuration. Thanks.
You can update it through the registry:
Get the adapter object (We need the GUID as the registry identifies the adapters by guid):
$adapter = Get-WmiObject Win32_NetworkAdapter | WHERE {$_.DeviceID -eq "1"}
Update the registry accordingly:
New-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$($adapter.guid)" -Name IPAddress -Value "10.91.62.201" -Force
I have a (at least what I think) tricky problem with a Server 2008 R2 domain. I wrote a cleanup script for AD computer accounts. Beside the account in AD I want to delete SCCM and DNS accounts. But with DNS I have a problem. I need to log everything as my script will run timed as a job each day.
With the normal AD module cmdlets all work great by using something like this:
Remove-ADComputer -Identity $account -confirm:$false
if($?){
Write-Log -LogContent "Delete-OldADaccount: successfully deleted account `"$($account.name)`" with LastLogondate `"$($account.LastLogondate)`", full path `"$($account.distinguishedname)`"" -LogPath $logFile
} else {
Write-Log -LogContent "Delete-OldADaccount: failed to delete account `"$($account.name)`": $($error[0].Exception.Message)" -LogPath $logFile -Level 'Warn'
}
For deleting old DNS entries I found two solutions for Server 2008 R2 (I can't use those cool new Server 2012 DNS modules for ps):
dnscmd $DNSServer /RecordDelete $ZoneName $Computer A /f
and
Get-WmiObject -ComputerName $dnsserver -Namespace 'Root\MicrosoftDNS' -class MicrosoftDNS_AType -Filter "domainname = '$computer'" | Remove-WmiObject
But both commands (dnscmd and Remove-WmiObject) always return true, even if there were no records in DNS matching my computer account's name. So I cant use a similar construct as above.
So I tried something like this:
try{
[System.Net.DNS]::GetHostEntry($computer)
Get-WmiObject -ComputerName $dns -Namespace 'Root\MicrosoftDNS' -class MicrosoftDNS_AType -Filter "domainname = '$computer'" | Remove-WmiObject -whatif
Get-WmiObject -ComputerName $dns -Namespace 'Root\MicrosoftDNS' -class MicrosoftDNS_AAAAType -Filter "domainname = '$computer'" | Remove-WmiObject -whatif
Write-Log -LogContent "Delete-OldADaccount: successfully deleted DNS entry for `"$($computer)`"" -LogPath $logFile
}
catch {
Write-Log -LogContent "Delete-OldADaccount: failed to delete DNS entry for `"$($computer)`": $($error[0].Exception.Message)" -LogPath $logFile -Level 'Warn'
}
With the static function [System.Net.DNS]::GetHostEntry($computer) I test if there is at least an ipv4 entry (as ipv6 is deactivated on my system I would get an exception if there is only an ipv6 entry. If both ipv4 and ipv6 exist it works). If there is an entry it proceeds with the Remove-WmiObject cmdlet for ipv4 and ipv6.
If there is no such entry in DNS I get an exception and directly jump into the catch-block where I log the error.
But even with this method I have no clue later if the Remove-WmiObject was successful. I would have to do a ipconfig /flushdns and re-run the command [System.Net.DNS]::GetHostEntry($computer) to see if it now fails and interpret this as "entries deleted".
Please, is there another cmdlet or way for Server 2008 R2 to delete an entry from DNS and validate if the deletion was successful? Help ;)
I can't use those cool new Server 2012 DNS modules for ps
Yes you can, as long as you have at least one machine new enough to run them. They work just fine against a 2008 R2 domain controller. This would simplify things a lot!
Otherwise, you can still use CIM/WMI calls to retrieve the value of the record like you're already doing instead of using GetHostEntry.
Example, courtesy of Jon Dechiro
if (Get-WmiObject -ComputerName $dnsserver -Namespace 'Root\MicrosoftDNS' -class MicrosoftDNS_AType -Filter "domainname = '$computer'") {
Write-Log -LogContent "Delete-OldADaccount: failed to delete DNS entry for "$($computer)": Entry still exists on $dnsserver" -LogPath $logFile -Level 'Warn'
} else {
Write-Log -LogContent "Delete-OldADaccount: successfully deleted DNS entry for "$($computer)"" -LogPath $logFile
}