I have a simple script to resolve hostname into IP address and then create from it key-value pair to use in jenkins:
$ips = Resolve-DnsName -type a HOSTNAME | FT IPAddress -HideTableHeaders
echo $ips
>> 192.168.3.1
But when I want to use this output in key-value pair, I receve following:
$keyvalue = $(echo 'ipaddr:'"$ips")
PS C:\Users\vegas.s> echo $keyvalue
ipaddr:
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
I want to receive following:
ipaddr:192.168.3.1
What am I doing wrong?
try this:
#join the string and ip separated by colon
$keyvalue = 'ipaddr',$ips -join ':'
PS C:\Users\vegas.s> echo $keyvalue
How to export the below with only the value.
Currently it exports below like this: PC IPv4 Address. . . . . . . . . . . : 192.168.30.50.
i would like the output to be: PC 192.168.30.50
script:
$ip = ipconfig | Select-String IPv4
$Host2 = Hostname
"$Host2 $ip" | Out-File "\\pc\c$\temp\Ipconfig.csv" -Append
Try this:
$hostname = hostname
ipconfig | where {$_ -match 'IPv4.+\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' } >> $null
$ip=$Matches[1]
$Final_output = "$Hostname : $ip "
$Final_output
I'm trying to use a PowerShell script to extract my local network IP address from the output of ipconfig. I have gotten it working using a temporary output file but would like to eliminate that step and just use a variable inside the script. I cannot figure out why my script that isn't using a temporary output file won't work. Any help would be much appreciated.
Here are the two scripts. First, the working version:
$input_path = 'C:\Users\Will\Code\Scripts\tmp.txt'
$regex = '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'
ipconfig | select-string "IPv4" | select-string -notmatch "192.168.56." > tmp.txt
$ipAddress = select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
# Pop up an alert window with the IP address
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup($ipAddress,0,"Done",0x1)
# Copy the IP address to the clipboard
$ipAddress | CLIP
And now the almost identical, but non-working version using only variables:
$regex = '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'
$input = ipconfig | select-string "IPv4" | select-string -notmatch "192.168.56."
#$input > inputVar.txt
$ipAddress = select-string -inputObject $input -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
# Pop up an alert window with the IP address
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup($ipAddress,0,"Done",0x1)
# Copy the IP address to the clipboard
$ipAddress | CLIP
I am using select-string to find the lines containing 'IPv4' piped into another call to select-string to eliminate the line containing the IP address of my virtual machine. If I enable the test output on line 6 of the non-working script and compare it to the 'tmp.txt' file from the working script, I can see that up to this point, both scripts work identically.
Furthermore, lines 10-15 in both scripts are identical. So I believe that the only line in question is #8.
I have tried it every way I can think of, but always get the same result ("IPv4" rather than the IP address) The first script works as expected and gives me the IP.
Both of these options seem like they should work (and are probably the most logical of all that I've tried), but neither gives me the IP:
$ipAddress = select-string -inputObject $input -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
and
$ipAddress = $input | select-string -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
I've even tried eliminating all the extra steps and just making one long pipe like this:
$ipAddress = ipconfig | select-string "IPv4" | select-string -notmatch "192.168.56." | select-string -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
and just copying to the clipboard like this:
ipconfig | select-string "IPv4" | select-string -notmatch "192.168.56." | select-string -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } | CLIP
But nothing seems to work.
Where have I gone wrong with this?
Thanks!
Updates 03/13/2015 6:30pm
I'm running Windows 7 64bit
Here's the output of $PSVersionTable:
Name Value
---- -----
CLRVersion 2.0.50727.5485
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
And yes, my end goal is just to get the IP. Really, I just wanted to find a quick way to do that. I guess I didn't technically need the IP by itself for what I'm using it for, but then once I got into it, I got pretty caught up in trying to figure the rest of this out just out of curiosity.
Thanks for all the help!
I'm just getting back into coding after a ~10 year break and I'm super rusty.
I'm not sure why my non working version isn't working for me if it's working for you. When I run it, I get "IPv4" in the pop up and on the clipboard, rather than the IP (which I get in the working version that uses the temp file.
I'm going to integrate these regex changes to my current script and play around with your gwmi solution, Matt. An initial run isn't returning anything for me, but I'll toy around with it and let you know.
Let me know if you have any more ideas on why the version with the variable isn't working correctly on my end in light of this updated info. It's totally baffling to me.
Thanks again!
Updates 03/13/2015 10:27pm
Here's the output of $PSVersionTable after the update:
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.18444
BuildVersion 6.3.9600.16406
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
Here is what happens if I run the Piped Commands piece by piece in PowerShell. As you can see, it seems to break on line 14 at:
$ipAddress = $ipAddress | % { $_.Matches }
Anyhow, thought this might help:
PS C:\Users\Will\Code> $regex = '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'
PS C:\Users\Will\Code> $inputVar = ipconfig | select-string "IPv4" | select-string -notmatch "192\.168\.56\."
PS C:\Users\Will\Code> $inputVar
IPv4 Address. . . . . . . . . . . : 192.168.0.105
PS C:\Users\Will\Code> $ipAddress = select-string -inputObject $inputVar -Pattern $regex -AllMatches
PS C:\Users\Will\Code> $ipAddress
IPv4 Address. . . . . . . . . . . : 192.168.0.105
PS C:\Users\Will\Code> $ipAddress = $ipAddress | % { $_.Matches }
PS C:\Users\Will\Code> $ipAddress
Groups : {IPv4}
Success : True
Captures : {IPv4}
Index : 3
Length : 4
Value : IPv4
PS C:\Users\Will\Code> $ipAddress = $ipAddress | % { $_.Value }
PS C:\Users\Will\Code> $ipAddress
IPv4
PS C:\Users\Will\Code>
Found an issue with this line:
$input = ipconfig | select-string "IPv4" | select-string -notmatch "192.168.56."
You cannot use $input the way you're trying to use it here.
It is one of the default variables in Powershell. Change the instances of $input to $iplist or another variable name.
Updated answer based on your latest edit:
Odd seeing it select IPv4 like that. I don't get the same results here. Try this, it is similar to Matt's method, but skips a couple of the Foreach-Object calls.
$ipAddress = (select-string -inputObject $inputVar -Pattern $regex -AllMatches).tostring().split(" ")[-1]
I should note this may not be the best process if you have multiple network adapters returned. In my case I have three and this only selects the last one.
Chaining Select-String
I think that is the issue you are having. That and you are treating Select-String like Where-Object. Consider the following
ipconfig | select-string "IPv4" | % { $_.Matches } | % { $_.Value }
The results of this would be at least one string that is IPv4 since that is exactly what you are asking for. Understand that select-string does not return strings but Microsoft.PowerShell.Commands.MatchInfo objects. I can imagine what is going on through your head would be "but my output should the strings?". That is why you see most uses of Select-String use % { $_.Matches } | % { $_.Value } to extract the matched strings.
There is a difference in what PowerShell is willing to show you on console and the actual underlying object. Not sure if you need more explanation. This edit would make your code work in place:
ipconfig | select-string "IPv4" | out-string |
select-string -notmatch "192.168.56." | out-string |
select-string -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
Still, that seems a little odd as the first Select-Strings are acting like Where clauses like I already mentioned. You could also do this then:
ipconfig | Where-Object {$_ -match "IPv4" -and $_ -notmatch "192\.168\.56\." } |
select-string -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }
Other approaches
I don't see any issues with you non-working version but I would like to offer an improvement to you select-string's since you don't exactly need to use more than one with some minor changes.
$ipAddressPrefix = [regex]::Escape("169.254.125.")
$ipaddresses = ipconfig | select-string "IPv4.*?: (?!$ipAddressPrefix).*" | % { $_.Matches } | % {$_.Value.Split(": ")[-1]}
# Pop up an alert window with the IP address
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup($ipaddresses,0,"Done",0x1)
Lets take the first 3 octets that you are trying to not match and make an escaped matching string. Then using a negative lookahead we match the lines containing "IPv4" but that don't have the $ipAddressPrefix following the colon.
Then, using all matches returned we split the string on the colon and space to get the IpAddresses matched. Again, note that it is very possible to get more than one address returned in this way.
Preferntial Method
Parsing string to get this information is fine and dandy but you can get it much easier using WMI and not having to working about things like leading and trailing spaces
$ipAddressPrefix = [regex]::Escape("169.254.125.")
$ipaddresses = gwmi Win32_NetworkAdapterConfiguration | Where { $_.IPAddress -and ($_.IPAddress -notmatch "$ipAddressPrefix|:") } |
Select -Expand IPAddress
$ipaddresses should contain the same results using either code snippet. The Where clause is broken down into these two parts
$_.IPAddress --> this would filter out empty strings and nulls
$_.IPAddress -notmatch "$ipAddressPrefix|:" would ensure that the $ipAddressPrefix matches are ommited. You will also see the : which will omit the IPv6 addresses.
I need to read the Ethernet adapter name from a PowerCli string so I can, through a script, and without user interaction, use it to change the ip address on a windows machine.
Here is how the powerCli string, from where I'm going to read the substring, will look:
C:\> $myIpInfoString
ScriptOutput
|
| Windows IP Configuration
|
|
| Ethernet adapter Local Area Connection 6:
|
| Connection-specific DNS Suffix . :
| Autoconfiguration IPv4 Address. . : 255.255.255.255
| Subnet Mask . . . . . . . . . . . : 255.255.255.255
| Default Gateway . . . . . . . . . :
|
how can I end up with another string variable that includes something like:
C:\>$myGoalString
Local Area Connection 6
The reason why this is important is because the number 6 changes from one machine to the other and can be, for example, "Local Area Connection 15".
Use Select-String:
$myGoalString = $myIpInfoStrong |
Select-String '^[\s\S]*?Ethernet adapter (.*?):' |
select -Expand Matches | select -Expand Groups |
select -Last 1 Value
With PowerShell v3 or newer you can simplify that a little, like this:
$myGoalString = $myIpInfoStrong |
Select-String '^[\s\S]*?Ethernet adapter (.*?):' |
% { $_.Matches.Groups[1].Value }
I am trying to get a list of IP addresses from several servers defined in server.txt.
Each server has 2 IP addresses and 2 FQDN.
Example:
servername (Production lan):server1 IPaddress:147.111.111.16
servername (backup lan):server1-bck IPaddress:10.0.4.12
Here is the code I'm using:
$servers = Get-Content server.txt
$server2 = "$servers-bck"
$zai = ""
foreach ($server in $servers)
{
$zai = $zai + $server + "`t" +
([System.Net.Dns]::GetHostAddresses($server) | foreach {echo $_.IPAddressToString}) +
"`t" +
([System.Net.Dns]::GetHostAddresses($server2) | foreach {echo $_.IPAddressToString}) +
"`n"
}
$zai > IP-address.csv
Unfortunately only the IP for Production lan is correct. The IP for backup lan only shows the IP of the last server in server.txt. I assume the problem is in: "foreach { echo $._IPAddressToString". I don't know how to fix it.
Any idea or advice will be helpful.
You seem to assume that
$server2="$servers-bck"
would append -bck to the name of each element in the array $servers. That is not the case. Instead, the array is expanded by joining its elements using the output field separator, so that -bck ends up after the last array element:
PS C:\> $a = 'a', 'b', 'c'
PS C:\> $a
a
b
c
PS C:\> "$a-bck"
a b c-bck
To get the backup server for each server from your list you need to append -bck inside the loop:
...([System.Net.Dns]::GetHostAddresses("$server-bck"))...
As a side-note, you shouldn't build CSVs manually. Let PowerShell do that for you:
$servers | % {
New-Object -Type PSObject -Property #{
'Name' = $_
'Production' = ([Net.Dns]::GetHostAddresses($_) | select -Expand IPAddressToString) -join ' '
'Backup' = ([Net.Dns]::GetHostAddresses("$_-bck") | select -Expand IPAddressToString) -join ' '
}
} | Export-Csv 'IP-address.csv' -NoType -Delimiter "`t"