Change IP as user with powershell script on Win 7 - powershell

On my Windows 7 Embedded machine I want to change the IP address via Powershell script as an user.
For that I added my user to the "Network Configuration Operators" group and wrote the following script.
param(
[string]$Type
)
Write-Host "Networkchanger"
$adapter = Get-WmiObject win32_NetworkAdapterConfiguration -filter "Index = 11"
if($Type -eq "black"){
Write-Host "Using black"
$IP = "192.168.1.172"
$Netmask = "255.255.255.0"
$Gateway = "192.168.1.1"
$DNS = "192.168.1.254"
$adapter.EnableStatic($IP, $NetMask)
Sleep -Seconds 4
$adapter.SetGateways($Gateway)
$adapter.SetDNSServerSearchOrder($DNS)
} else {
Write-Host "Using rf"
$adapter.SetDNSServerSearchOrder()
$adapter.EnableDHCP()
}
The script runs fine as admin, but not as an user. Did I forget to add some rights to the script or user?
Edit:
When I click "Run as admin" and use black it works for the first time. After changing it to rf (which works), the black net just changes the Gateway and DNS, but not the IP and Netmask, which confuses me.

You are correct that admin rights are required for setting a static IP address. I do it on our Windows Embedded Standard 7 images. Essentially, I created a shortcut on the desktop with Run As Administrator for launching PowerShell with the particular script. Also note that no such elevated permission is required to enable DHCP, but it doesn't hurt.
There is a slightly simpler way to set the IP address from PowerShell, using the netsh command. The good thing about this approach is that you can see the specific error from a command prompt also. Try switching back and forth from an elevated command prompt and a non-elevated one.
netsh interface ip set address "${InterfaceName}" static addr=${IPAddr} mask=${Mask} gateway=${Gateway}
netsh interface ip set address "${InterfaceName}" dhcp

I've solved the problem by heavily modifing my Powershell script:
$id=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal=New-Object System.Security.Principal.WindowsPrincipal($id)
if(!$principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
$powershell=[System.Diagnostics.Process]::GetCurrentProcess()
$psi=New-Object System.Diagnostics.ProcessStartInfo $powershell.Path
$script=$MyInvocation.MyCommand.Path
$prm=$script+$Type
foreach($a in $args) {
$prm+=' '+$a
}
$psi.Arguments=$prm
$psi.Verb="runas"
[System.Diagnostics.Process]::Start($psi) | Out-Null
return;
}
Write-Host "Networkchanger"
Write-Host ""
Write-Host "[0] cancel"
Write-Host "[1] net1: 10.0.0.172"
Write-Host "[2] net2: 192.168.178.(172,235,237,248,251)"
$adapter = Get-WmiObject win32_NetworkAdapterConfiguration -filter "Index = 0"
$loop = 1;
while($loop -eq 1){
$Type = Read-Host -Prompt '0, 1 OR 2'
switch($Type){
0 {
Write-Host "Cancel Process"
Sleep -Seconds 3
exit
}
1 {
Write-Host "Using sb"
$IP = "10.0.0.172"
$Netmask = "255.255.255.0"
$Gateway = "10.0.0.1"
$DNS = "10.0.0.254"
$adapter.EnableStatic($IP, $NetMask)
Sleep -Seconds 4
$adapter.SetGateways($Gateway)
$adapter.SetDNSServerSearchOrder($DNS)
$loop = 0
}
2 {
Write-Host "Using rf"
$macaddress = $adapter | select -expand macaddress
Write-Host $macaddress
$IP = ""
if ($macaddress -eq "xx:xx:xx:xx:xx:xx"){
$IP = "192.168.178.172"
} elseif ($macaddress -eq "xx:xx:xx:xx:xx:xx") {
$IP = "192.168.178.235"
} elseif ($macaddress -eq "xx:xx:xx:xx:xx:xx") {
$IP = "192.168.178.237"
} elseif ($macaddress -eq "xx:xx:xx:xx:xx:xx") {
$IP = "192.168.178.248"
} elseif ($macaddress -eq "xx:xx:xx:xx:xx:xx") {
$IP = "192.168.178.251"
} else {
Write-Host "Mac address not in list"
Sleep -Seconds 5
exit
}
$Netmask = "255.255.255.0"
$Gateway = "192.168.178.1"
$DNS = "192.168.178.2","192.168.178.3"
$adapter.EnableStatic($IP, $NetMask)
Sleep -Seconds 4
$adapter.SetGateways($Gateway)
$adapter.SetDNSServerSearchOrder($DNS)
$loop = 0
}
}
}
Write-Host "Current IP: "
ipconfig
Start-Sleep -seconds 5

Related

Powershell script Changing DNS properties working on 32 bit system but not working on 64 bit

This is the script that changes the configuration of DNS properties like setting the IP address, Default Gateway, and DNS server address which can be found at Control Panel -> Network and sharing center -> select adapter -> Properties -> Internet Protocol Version 4(TCP/IPv4).
This script is running perfectly on windows 7 32-bit and windows 10 32-bit systems but for some reason, it's not working on windows 7 64 bit. Whenever I try to change the IP address it throws the error code 97 i.e. Interface not configurable. If I use the function on the adapter directly in PowerShell command line like $adapter = (get-wmiobject win32_networkadapterconfiguration | where-object {$_.index -eq 7})
$adapter.EnableStatic("192.168.1.50", "255.255.255.0")
it's working on the Powershell command-line user interface. I can't figure out why or how is it happening?
UPDATE:
I tried to debug the code and I found that for some reason I can't fetch AdapterIndex from hash_Table network_info like
$network_info = Get-IPAdapterInformation
[string]$AdapterName = $network_info.AdapterName
[string]$AdapterInterfaceIndex = $network_info.AdapterInterfaceIndex
[string]$AdapterIndex = $network_info.AdapterIndex
cls
#function to get Adapter Info based on Mac-Address
function Get-IPAdapterInformation{
# [CmdletBinding()]
$AdapterInfo = #{}
# $MyMacAddress = "00:15:5D:00:A3:07"
$MyMacAddress = Read-Host "Enter Mac Address of Adapter"
$MyMacAddress = $MyMacAddress.Trim()
Try { $IPconfigset = Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "root\CIMv2" -ErrorAction:Stop | ? {$_.IPEnabled -and ($_.MACAddress -ne $null)} } Catch { return $IPs }
foreach ($ip in $IPconfigset) {
if($ip.MACAddress -eq $MyMacAddress){
$i = New-Object PSObject | Select-Object Index, InterfaceIndex, IPAddress, Subnet, Name, DeviceName, MACAddress, DNSSearchOrder, Gateway, Status
$i.Index = $ip.Index
$i.InterfaceIndex = $ip.InterfaceIndex
$i.IPAddress = $ip.IPAddress[0]
$i.Subnet = $ip.IPSubnet[0]
$i.DeviceName = $ip.Description
$i.MACAddress = $ip.MACAddress
$i.DNSSearchOrder = $ip.DNSServerSearchOrder
$i.Gateway = $ip.DefaultIPGateway
$i.Name = (Get-WmiObject win32_networkadapter -ErrorAction:SilentlyContinue | ? {$_.Name -eq $i.DeviceName}).netconnectionid
$i.Status = (Get-WmiObject win32_networkadapter -ErrorAction:SilentlyContinue | ? {$_.Name -eq $i.DeviceName}).NetConnectionStatus
$AdapterInfo.add('AdapterName', $i.Name)
$AdapterInfo.add('AdapterInterfaceDescription', $i.DeviceName)
$AdapterInfo.add('AdapterInterfaceIndex', $i.InterfaceIndex)
$AdapterInfo.add('AdapterIndex', $i.Index)
}
}
if($AdapterInfo -ne $null){
Write-Host "Adapter Found!" -ForegroundColor Green
Write-Host "Adapter Name:"$AdapterInfo.AdapterName -ForegroundColor Green
Write-Host "Adapter InterfaceIndex:"$AdapterInfo.AdapterInterfaceIndex -ForegroundColor Green
Write-Host "Adapter Interface Description:"$AdapterInfo.AdapterInterfaceDescription -ForegroundColor Green
Write-Host "Adapter Index:"$AdapterInfo.AdapterIndex -ForegroundColor Green
}else{
Write-Host "No Adapter found with given MacAddress" -ForegroundColor Ref
}
return $AdapterInfo
}
#====================================================================
# STEP #2: SETUP NETWORK
#====================================================================
Write-Host "Available Network Adapters on this Device:" -ForegroundColor Green
Get-WmiObject Win32_networkAdapter | ?{$_.MACAddress -ne $null} | Select NetConnectionID, Name, MACAddress, Description, InterfaceIndex, NetConnectionStatus
$network_info = Get-IPAdapterInformation
#$network_info
[string]$AdapterName = $network_info.AdapterName
[string]$AdapterInterfaceIndex = $network_info.AdapterInterfaceIndex
[string]$AdapterIndex = $network_info.AdapterIndex
#Returns StatusCode Description based on given status code
function Get-StatusCodeDescripton($StatusCode){
Switch($StatusCode){
0{
return "Successful completion, no reboot required"
}1{
return "Successful completion, reboot required"
}64{
return "Method not supported on this platform"
}65{
return "Unknown failure"
}66{
return "Invalid subnet mask"
}67{
return "An error occurred while processing an Instance that was returned"
}68{
return "Invalid input parameter"
}69{
return "More than 5 gateways specified"
}70{
return "Invalid IP address"
}71{
return "Invalid gateway IP address"
}72{
return "An error occurred while accessing the Registry for the requested information"
}73{
return "Invalid domain name"
}74{
return "Invalid host name"
}75{
return "No primary/secondary WINS server defined"
}76{
return "Invalid file"
}77{
return "Invalid system path"
}78{
return "File copy failed"
}79{
return "Invalid security parameter"
}80{
return "Unable to configure TCP/IP service"
}81{
return "Unable to configure DHCP service"
}82{
return "Unable to renew DHCP lease"
}83{
return "Unable to release DHCP lease"
}84{
return "IP not enabled on adapter"
}85{
return "IPX not enabled on adapter"
}86{
return "Frame/network number bounds error"
}87{
return "Invalid frame type"
}88{
return "Invalid network number"
}89{
return "Duplicate network number"
}90{
return "Parameter out of bounds"
}91{
return "Access denied"
}92{
return "Out of memory"
}93{
return "Already exists"
}94{
return "Path, file or object not found"
}95{
return "Unable to notify service"
}96{
return "Unable to notify DNS service"
}97{
return "Interface not configurable"
}98{
return "Not all DHCP leases could be released/renewed"
}100{
return "DHCP not enabled on adapter"
}101{
return "Some error occured!"
}default{
return "Some Unknown error occurred!"
}
}
}
#Set IP address(Input: IPAddrss, DefaultGateway, SubnetMask(Optional))
function Set-IPAddress{
[CmdletBinding()]
Param(
#IP Address
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[String]$IPAddress,
#Default Gateway
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[String]$DefaultGateway
)
$IPAddress
$SubNetMask = Read-Host "Enter Subnet Mask[Default 255.255.255.0]"
if(-not $SubNetMask){
$SubNetMask ="255.255.255.0"
}
$SubNetMask
$adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
$IPandSubnetMaskResult = $adapter.EnableStatic($IPAddress, $SubNetMask) #IPAddress, Subnet Mask
$IPandSubnetMaskResultCode = $IPandSubnetMaskResult.ReturnValue
$IPandSubnetMaskResultCode
$IPandSubnetMaskResultDesciption = Get-StatusCodeDescripton($IPandSubnetMaskResultCode)
if(($IPandSubnetMaskResultCode -eq 0) -or ($IPandSubnetMaskResultCode -eq 1)){
Write-Host $IPandSubnetMaskResultDesciption -ForegroundColor Green
Write-Host "[SUCCESS] Changed Static IP Address to: $($IPAddress)." -ForegroundColor Green
}else{
Write-Host $IPandSubnetMaskResultDesciption -ForegroundColor Red
}
$GatewayResult = $adapter.SetGateways($DefaultGateway)
$GatewayResultCode = $GatewayResult.ReturnValue
$GatewayResultDescription = Get-StatusCodeDescripton($GatewayResultCode)
if(($GatewayResultCode -eq 0) -or ($GatewayResultCode -eq 1)){
Write-Host $GatewayResultDescription -ForegroundColor Green
Write-Host "[SUCCESS] Changed Default GAteway to: $($DefaultGateway)." -ForegroundColor Green
}else{
Write-Host $GatewayResultDescription -ForegroundColor Red
Write-Host "An Error occurred!" -ForegroundColor Red
}
Sleep -Seconds 4 #sometimes setting instantly IP address gives error 67.
}
#Set DNS Server Address(Input:PrimaryDNSAddress, SecondaryDNSAddress(Optional))
function Set-DNSServerAdddress{
[CmdletBinding()]
Param(
#Primary DNS Server Address
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[String]$PrimaryDNSAddress
)
$SecondaryDNSAddress = Read-Host "Enter Secondary DNS Address[Optional]"
$adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
if($SecondaryDNSAddress){
$SetDNSServerAddressResult = $adapter.SetDNSServerSearchOrder(#($PrimaryDNSAddress, $SecondaryDNSAddress))
}else{
$SetDNSServerAddressResult = $adapter.SetDNSServerSearchOrder(#($PrimaryDNSAddress))
}
$SetDNSServerAddressResultCode = $SetDNSServerAddressResult.ReturnValue
$SetDNSServerAddressResultDescription = Get-StatusCodeDescripton($SetDNSServerAddressResult)
if(($SetDNSServerAddressResultCode -eq 0) -or ($SetDNSServerAddressResultCode -eq 1)){
Write-Host $SetDNSServerAddressResultDescription -ForegroundColor Green
Write-Host "[SUCCESS] Set DNS Servers to: $($PrimaryDNSAddress), $($SecondaryDNSAddress)." -ForegroundColor Green
}else{
Write-Host $GatewayResultDescription -ForegroundColor Red
Write-Host "An Error occurred!" -ForegroundColor Red
}
Sleep -Seconds 4
}
function Set-DNSSererAddressAutomatically{
$userInput = Read-Host "Do you want to set DNS Server Address Automatically? [y]Yes [n]No[Default NO]"
if($userInput -eq "y" -or $userInput -eq "yes"){
$adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
$SetDNSServerAddressAutomaticallyResult = $adapter.SetDNSServerSearchOrder()
$SetDNSServerAddressAutomaticallyResultCode = $SetDNSServerAddressAutomaticallyResult.ReturnValue
$SetDNSServerAddressAutomaticallyResultDescription = Get-StatusCodeDescripton($SetDNSServerAddressAutomaticallyResultCode)
if(($SetDNSServerAddressAutomaticallyResultCode -eq 0) -or ($SetDNSServerAddressAutomaticallyResultCode -eq 1)){
Write-Host $SetDNSServerAddressAutomaticallyResultDescription -ForegroundColor Green
Write-Host "[SUCCESS] Set DNS Servers Automatically." -ForegroundColor Green
}else{
Write-Host $SetDNSServerAddressAutomaticallyResultDescription -ForegroundColor Red
Write-Host "An Error occurred!" -ForegroundColor Red
}
}else{
Write-Warning "You selected NO"
}
Sleep -Seconds 4
}
function Set-IPAddressAutomatically{
$userInput = Read-Host "Set IP Automatically? [y]Yes [n]No[Default NO]"
if($userInput -eq "y" -or $userInput -eq "yes"){
$adapter = (get-wmiobject win32_networkadapterconfiguration -ErrorAction:SilentlyContinue | where-object {$_.index -eq $AdapterIndex})
$SetIPAddressAutomaticallyResult = $adapter.EnableDHCP()
$SetIPAddressAutomaticallyResultCode = $SetIPAddressAutomaticallyResult.ReturnValue
$SetIPAddressAutomaticallyResultDescription = Get-StatusCodeDescripton($SetIPAddressAutomaticallyResultCode)
if(($SetIPAddressAutomaticallyResultCode -eq 0) -or ($SetIPAddressAutomaticallyResultCode -eq 1)){
Write-Host $SetIPAddressAutomaticallyResultDescription -ForegroundColor Green
Write-Host "[SUCCESS] Set IP Addresss Automatically." -ForegroundColor Green
}else{
Write-Host $SetIPAddressAutomaticallyResultDescription -ForegroundColor Red
Write-Host "An Error occurred!" -ForegroundColor Red
}
}else{
Write-Warning "You selected NO"
}
Sleep -Seconds 4
}
#Set-IPAddress #working
#Set-DNSServerAdddress #not working with2nd DNS Server Address
#Set-DNSSererAddressAutomatically # working
#Set-IPAddressAutomatically #working
$choices = "Select Operation:
0. Print Choices
1. Set IP Address and Default Gateway
2. Set DNS Server Address
3. Set IP Address Automatically
4. Set DNS Server Address Automatically
t. exit/terminate
"
$status = $true
while($status){
$choice = Read-Host "Select choice: $choices"
$choice
switch($choice){
0{
Write-Host " ==> Print choices: $choices" -ForeGround Green
break
}
1{
Write-Host " ==> Set IP Address and Default Gateway" -ForeGround Green
Set-IPAddress
break
}
2{
Write-Host " ==> Set DNS Server Address" -ForeGround Green
Set-DNSServerAdddress
break
}
3{
Write-Host " ==> Set IP Address Automatically" -ForeGround Green
Set-IPAddressAutomatically
break
}
4{
Write-Host " ==> Set DNS Server Address Automatically"
Set-DNSSererAddressAutomatically
break
}
t{
Write-Host " ==> Exit" -ForeGround Green
$status = $false
}
}
}
#Index : 7
#InterfaceIndex : 11
#IPAddress : 192.168.234.197
#Subnet : 255.255.240.0
#Name : Local Area Connection
#DeviceName : Microsoft Virtual Machine Bus Network Adapter
#MACAddress : 00:15:5D:00:A3:07
#DNSSearchOrder : {192.168.224.1}
#Gateway : {192.168.224.1}
#Status : 2
I did go ahead and run the entire script as-is up to where you were having trouble at $network_info.AdapterIndex on a machine running Windows 7 64-bit, and I'm able to pull the $AdapterIndex without issues, so it may just be that VM?
I would also recommend feeding $AdapterIndex as a parameter to your other functions instead of basically using it as a global variable.
For the issue of not being able to access an element of a hashtable, I believe the problem is probably earlier in your script. For example, you're not really checking if $network_info has any data. My guess would be something like your WMI query on that VM doesn't actually return a valid object. Try out something like this on the 64-bit win7 VM - basically just removing some of the function structures and -erroraction SilentlyContinue flags:
$MyMacAddress = "00:00:00:3C:7A:00" # yours here
$MatchingAdapter = Get-WmiObject Win32_NetworkAdapterConfiguration |
Where {$_.IPEnabled -and ($_.MACAddress -eq $MyMacAddress )}
# double-check you actually found an adapter via MAC
if (!$MatchingAdapter) {throw "No adapter found with MAC address $MyMacAddress";break}
$AdapterInfo = #{
AdapterName = (
Get-WmiObject -Query "SELECT netconnectionID FROM win32_networkadapter WHERE Name = '$($MatchingAdapter.Description)'"
).netconnectionid
AdapterInterfaceDescription = $MatchingAdapter.Description
AdapterInterfaceIndex = $MatchingAdapter.InterfaceIndex
AdapterIndex = $MatchingAdapter.Index
}
[PSCustomObject]$AdapterInfo | fl
If that returns reasonable values, then this should work too:
$Adapter = Get-WMIObject -Query "SELECT * FROM win32_networkadapterconfiguration WHERE index = '$($MatchingAdapter.Index)'"
$IPandSubnetMaskResult = $adapter.EnableStatic($IPAddress, $SubNetMask)

How to ping continuously in the background in powershell?

This is my first program in powershell, Im trying to get from the user input and then pinging the IP address or the hostname, Creating text file on the desktop.
But if the user wants the add more than one IP I get into infinite loop.
Here Im asking for IP address.
$dirPath = "C:\Users\$env:UserName\Desktop"
function getUserInput()
{
$ipsArray = #()
$response = 'y'
while($response -ne 'n')
{
$choice = Read-Host '
======================================================================
======================================================================
Please enter HOSTNAME or IP Address, enter n to stop adding'
$ipsArray += $choice
$response = Read-Host 'Do you want to add more? (y\n)'
}
ForEach($ip in $ipsArray)
{
createFile($ip)
startPing($ip)
}
}
Then I creating the file for each IP address:
function createFile($ip)
{
$textPath = "$($dirPath)\$($ip).txt"
if(!(Test-Path -Path $textPath))
{
New-Item -Path $dirPath -Name "$ip.txt" -ItemType "file"
}
}
And now you can see the problem, Because I want the write with TIME format, I have problem with the ForEach loop, When I start to ping, And I cant reach the next element in the array until I stop
the cmd.exe.
function startPing($ip)
{
ping.exe $ip -t | foreach {"{0} - {1}" -f (Get-Date), $_
} >> $dirPath\$ip.txt
}
Maybe I should create other files ForEach IP address and pass params?
Here's a old script I have. You can watch a list of computers in a window.
# pinger.ps1
# example: pinger yahoo.com
# pinger c001,c002,c003
# $list = cat list.txt; pinger $list
param ($hostnames)
#$pingcmd = 'test-netconnection -port 515'
$pingcmd = 'test-connection'
$sleeptime = 1
$sawup = #{}
$sawdown = #{}
foreach ($hostname in $hostnames) {
$sawup[$hostname] = $false
$sawdown[$hostname] = $false
}
#$sawup = 0
#$sawdown = 0
while ($true) {
# if (invoke-expression "$pingcmd $($hostname)") {
foreach ($hostname in $hostnames) {
if (& $pingcmd -count 1 $hostname -ea 0) {
if (! $sawup[$hostname]) {
echo "$([console]::beep(500,300))$hostname is up $(get-date)"
$sawup[$hostname] = $true
$sawdown[$hostname] = $false
}
} else {
if (! $sawdown[$hostname]) {
echo "$([console]::beep(500,300))$hostname is down $(get-date)"
$sawdown[$hostname] = $true
$sawup[$hostname] = $false
}
}
}
sleep $sleeptime
}
pinger microsoft.com,yahoo.com
microsoft.com is down 11/08/2020 17:54:54
yahoo.com is up 11/08/2020 17:54:55
Have a look at PowerShell Jobs. Note that there are better and faster alternatives (like thread jobs, runspaces, etc), but for a beginner, this would be the easiest way. Basically, it starts a new PowerShell process.
A very simple example:
function startPing($ip) {
Start-Job -ScriptBlock {
param ($Address, $Path)
ping.exe $Address -t | foreach {"{0} - {1}" -f (Get-Date), $_ } >> $Path
} -ArgumentList $ip, $dirPath\$ip.txt
}
This simplified example does not take care of stopping the jobs. So depending on what behavior you want, you should look that up.
Also, note there there is also PowerShell's equivalent to ping, Test-Connection

Create a variable from a Remote Ping Response IP Address

I need to be able to ping a range of IP addresses and when I get a reply on one, then capture that IP to put in a variable which I can use to update the local computers host file.
The purpose of this script is to be used for a Point-to-Site Azure VPN service. A remote server is connecting as a client and is given a second IP address which changes on each connection. The other server can only communicate to the remote server on this IP address, but the application it uses only uses DNS Names, so I will need to update the hosts file with the connecting servers IP each time it dials in.
$subnet = "172.16.201.0"
$start = 1
$end = 10
$ping = 1
while ($start -le $end) {
$IP = "172.16.201.$start"
Write-Host "Pinging $IP" -ForegroundColor Cyan
Test-Connection -ComputerName $IP -count 1 -Quiet
$start++
}
So far the above code only does a IP Sweep and outputs the success/failure of each IP. I need to capture the success IP and put that in a variable
i presume you want only the 1st responding IP address, not all the addresses in the range. [grin] you can turn this into a function fairly easily. you can also turn OFF the verbose output by commenting out the 2nd line.
$Old_VPref = $VerbosePreference
$VerbosePreference = 'Continue'
$Subnet = '192.168.1'
$RangeStart = 60
$RangeEnd = 69
$1stRespondingIPv4 = foreach ($Octet in $RangeStart..$RangeEnd)
{
$IP = $Subnet, $Octet -join '.'
$WV_Msg = 'Testing {0} ...' -f $IP
Write-Verbose -Message $WV_Msg
$Pingable = Test-Connection -ComputerName $IP -Count 1 -Quiet
if ($Pingable)
{
$IP
# the next line stops the foreach loop
break
}
}
''
$1stRespondingIPv4
$VerbosePreference = $Old_VPref
output ...
VERBOSE: Testing 192.168.1.60 ...
VERBOSE: Testing 192.168.1.61 ...
VERBOSE: Testing 192.168.1.62 ...
VERBOSE: Testing 192.168.1.63 ...
VERBOSE: Testing 192.168.1.64 ...
192.168.1.64
$dns = "domain.com"
$ipAddresses = #(
"172.16.201.0"
"172.16.201.1"
"172.16.201.2"
"172.16.201.3"
"172.16.201.4"
"172.16.201.5"
"172.16.201.6"
"172.16.201.7"
"172.16.201.8"
"172.16.201.9"
"172.16.201.10"
)
foreach($ip in $ipAddresses) {
Write-Host "Pinging $ip" -ForegroundColor Cyan
$ping = Test-Connection -ComputerName "$ip" -count 1 -Quiet
if ($ping) {
Add-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Value "$ip $dns"
Write-Host "The host file was updated with the successful IP and hostname: $ip $dns" -ForegroundColor Cyan
}
}

Batch file that change dns between 2 option

I'm trying to make a windows 10 batch file that swap my dns from 2 options. The first one is 8.8.8.8 (google dns) and the second one are a custom DNS that allows me to watch US netflix (like 90.90.90.90).
The bash command to change dns is
netsh interface ipv4 add dnsserver "Ethernet" address=8.8.8.8 index=1
the command to check which dns is up and running is:
nslookup
Now i want to do an IF THEN ELSE that work like this:
if (dns == 8.8.8.8)
then (change them to 90.90.90.90)
else (change them to 8.8.8.8)
Even a powershell script is fine
This should work:
#echo off
set "dns=8.8.8.8"
for /F "skip=1 tokens=2" %%a in ('nslookup^<NUL') do if "%%a" equ "8.8.8.8" set "dns=90.90.90.90"
netsh interface ipv4 add dnsserver "Ethernet" address=%dns% index=1
Basically:
# Setup the dos command process information:
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "nslookup"
$pinfo.Arguments = ""
$pinfo.UseShellExecute = $false
$pinfo.CreateNoWindow = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.RedirectStandardError = $true
# Start the process:
$process.Start() | Out-Null
# Wait a while for the process to do something:
sleep -Seconds 5
# If the process is still active kill it:
if (!$process.HasExited) {
$process.Kill()
}
# get output from stdout and stderr:
$stdout = $process.StandardOutput.ReadToEnd()
$stderr = $process.StandardError.ReadToEnd()
# Parse the IP address from the output:
$regex = [regex] "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"
$regex.Matches($stdout) | %{ $Condition = $_.value }
# Do your dns change based on the output:
if ($Condition -eq "8.8.8.8")
{
"set other dns"
}
Else
{
"set google dns"
}
Sorry I couldn't mature the answer a bit more; unexpected visitors.
-Edit:
Taking into account some of the comments, and a bug with my regular expression, this might be a more suitable solution:
[cmdletbinding()]
param ([parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [string[]]$ComputerName = $env:computername )
begin {}
process {
# get current DNS setting:
foreach ($Computer in $ComputerName) {
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0)
{
try {
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computer -EA Stop | ? {$_.IPEnabled}
}
catch
{
Write-Warning "Error occurred while querying $computer."
Continue
}
foreach ($Network in $Networks)
{
$Condition = $Network.DNSServerSearchOrder;
break;
}
}
}
# Do your dns change based on the output:
if ($Condition -eq "8.8.8.8")
{
"set other dns";
}
Else
{
"set google dns";
}
}
end {}

How to check Network port access and display useful message?

I was trying to check whether the port is opened or not using powershell like follows.
(new-object Net.Sockets.TcpClient).Connect("10.45.23.109", 443)
This method works , but the output is not user-friendly. It means if there are no errors then it has access. Is there any way to check for success and display some message like " Port 443 is operational"?
If you're running Windows 8/Windows Server 2012 or newer, you can use the Test-NetConnection command in PowerShell.
Ex:
Test-NetConnection -Port 53 -ComputerName LON-DC1
I improved Salselvaprabu's answer in several ways:
It is now a function - you can put in your powershell profile and use anytime you need
It can accept host as hostname or as ip address
No more exceptions if host or port unavaible - just text
Call it like this:
Test-Port example.com 999
Test-Port 192.168.0.1 80
function Test-Port($hostname, $port)
{
# This works no matter in which form we get $host - hostname or ip address
try {
$ip = [System.Net.Dns]::GetHostAddresses($hostname) |
select-object IPAddressToString -expandproperty IPAddressToString
if($ip.GetType().Name -eq "Object[]")
{
#If we have several ip's for that address, let's take first one
$ip = $ip[0]
}
} catch {
Write-Host "Possibly $hostname is wrong hostname or IP"
return
}
$t = New-Object Net.Sockets.TcpClient
# We use Try\Catch to remove exception info from console if we can't connect
try
{
$t.Connect($ip,$port)
} catch {}
if($t.Connected)
{
$t.Close()
$msg = "Port $port is operational"
}
else
{
$msg = "Port $port on $ip is closed, "
$msg += "You may need to contact your IT team to open it. "
}
Write-Host $msg
}
Actually Shay levy's answer is almost correct but i got an weird issue as i mentioned in his comment column. So i split the command into two lines and it works fine.
$Ipaddress= Read-Host "Enter the IP address:"
$Port= Read-host "Enter the port number to access:"
$t = New-Object Net.Sockets.TcpClient
$t.Connect($Ipaddress,$Port)
if($t.Connected)
{
"Port $Port is operational"
}
else
{
"Port $Port is closed, You may need to contact your IT team to open it. "
}
You can check if the Connected property is set to $true and display a friendly message:
$t = New-Object Net.Sockets.TcpClient "10.45.23.109", 443
if($t.Connected)
{
"Port 443 is operational"
}
else
{
"..."
}
With the latest versions of PowerShell, there is a new cmdlet, Test-NetConnection.
This cmdlet lets you, in effect, ping a port, like this:
Test-NetConnection -ComputerName <remote server> -Port nnnn
I know this is an old question, but if you hit this page (as I did) looking for this information, this addition may be helpful!
I tried to improve the suggestion from mshutov.
I added the option to use the output as an object.
function Test-Port($hostname, $port)
{
# This works no matter in which form we get $host - hostname or ip address
try {
$ip = [System.Net.Dns]::GetHostAddresses($hostname) |
select-object IPAddressToString -expandproperty IPAddressToString
if($ip.GetType().Name -eq "Object[]")
{
#If we have several ip's for that address, let's take first one
$ip = $ip[0]
}
} catch {
Write-Host "Possibly $hostname is wrong hostname or IP"
return
}
$t = New-Object Net.Sockets.TcpClient
# We use Try\Catch to remove exception info from console if we can't connect
try
{
$t.Connect($ip,$port)
} catch {}
if($t.Connected)
{
$t.Close()
$object = [pscustomobject] #{
Hostname = $hostname
IP = $IP
TCPPort = $port
GetResponse = $True }
Write-Output $object
}
else
{
$object = [pscustomobject] #{
Computername = $IP
TCPPort = $port
GetResponse = $False }
Write-Output $object
}
Write-Host $msg
}
If you are using older versions of Powershell where Test-NetConnection isn't available, here is a one-liner for hostname "my.hostname" and port "123":
$t = New-Object System.Net.Sockets.TcpClient 'my.hostname', 123; if($t.Connected) {"OK"}
Returns OK, or an error message.
Great answer by mshutov & Salselvaprabu. I needed something a little bit more robust, and that checked all IPAddresses that was provided instead of checking only the first one.
I also wanted to replicate some of the parameter names and functionality than the Test-Connection function.
This new function allows you to set a Count for the number of retries, and the Delay between each try. Enjoy!
function Test-Port {
[CmdletBinding()]
Param (
[string] $ComputerName,
[int] $Port,
[int] $Delay = 1,
[int] $Count = 3
)
function Test-TcpClient ($IPAddress, $Port) {
$TcpClient = New-Object Net.Sockets.TcpClient
Try { $TcpClient.Connect($IPAddress, $Port) } Catch {}
If ($TcpClient.Connected) { $TcpClient.Close(); Return $True }
Return $False
}
function Invoke-Test ($ComputerName, $Port) {
Try { [array]$IPAddress = [System.Net.Dns]::GetHostAddresses($ComputerName) | Select-Object -Expand IPAddressToString }
Catch { Return $False }
[array]$Results = $IPAddress | % { Test-TcpClient -IPAddress $_ -Port $Port }
If ($Results -contains $True) { Return $True } Else { Return $False }
}
for ($i = 1; ((Invoke-Test -ComputerName $ComputerName -Port $Port) -ne $True); $i++)
{
if ($i -ge $Count) {
Write-Warning "Timed out while waiting for port $Port to be open on $ComputerName!"
Return $false
}
Write-Warning "Port $Port not open, retrying..."
Sleep $Delay
}
Return $true
}
boiled this down to a one liner sets the variable "$port389Open" to True or false - its fast and easy to replicate for a list of ports
try{$socket = New-Object Net.Sockets.TcpClient($ipAddress,389);if($socket -eq $null){$Port389Open = $false}else{Port389Open = $true;$socket.close()}}catch{Port389Open = $false}
If you want ot go really crazy you can return the an entire array-
Function StdPorts($ip){
$rst = "" | select IP,Port547Open,Port135Open,Port3389Open,Port389Open,Port53Open
$rst.IP = $Ip
try{$socket = New-Object Net.Sockets.TcpClient($ip,389);if($socket -eq $null){$rst.Port389Open = $false}else{$rst.Port389Open = $true;$socket.close();$ipscore++}}catch{$rst.Port389Open = $false}
try{$socket = New-Object Net.Sockets.TcpClient($ip,53);if($socket -eq $null){$rst.Port53Open = $false}else{$rst.Port53Open = $true;$socket.close();$ipscore++}}catch{$rst.Port53Open = $false}
try{$socket = New-Object Net.Sockets.TcpClient($ip,3389);if($socket -eq $null){$rst.Port3389Open = $false}else{$rst.Port3389Open = $true;$socket.close();$ipscore++}}catch{$rst.Port3389Open = $false}
try{$socket = New-Object Net.Sockets.TcpClient($ip,547);if($socket -eq $null){$rst.Port547Open = $false}else{$rst.Port547Open = $true;$socket.close();$ipscore++}}catch{$rst.Port547Open = $false}
try{$socket = New-Object Net.Sockets.TcpClient($ip,135);if($socket -eq $null){$rst.Port135Open = $false}else{$rst.Port135Open = $true;$socket.close();$SkipWMI = $False;$ipscore++}}catch{$rst.Port135Open = $false}
Return $rst
}
When scanning closed port it becomes unresponsive for long time. It seems to be quicker when resolving fqdn to ip like:
[System.Net.Dns]::GetHostAddresses("www.msn.com").IPAddressToString