how to get 2 values out of a string - powershell

Im hoping someone can help me with where to start, I want to pull some data out of some larger data
My data looks like this:
IP-MIB::ipNetToMediaPhysAddress.13600001.10.4.48.1 = STRING: 36:b:7:0:41:31
IP-MIB::ipNetToMediaPhysAddress.13600001.10.4.49.21 = STRING: 3b:fa:a2:us:74:d9
IP-MIB::ipNetToMediaPhysAddress.13600001.10.3.50.22 = STRING: 3b:fa:a2:us:7b:f3
There is an IP Address on each line starting with 10. and the mac address which is on the end, thats what I want to get out.
Ive been googling and am not sure where to start/what to do.
Is Regex the way to go, or is there a better way, any examples would be appreciated.
Thanks in advance

here's one way to get that info ... [grin]
fake reading in a text file
you will most likely want to use Get-Content or some pre-existing collection.
iterate thru the collection
use a named-capture-group regex to match on the IP & MAC
create a PSCustomObject from the match data
you can get them from the $Matches automatic variable.
send the current object out to be collected by the $Results variable
display that collection
here's the code ...
# fake reading in a text file
# in real life, use Get-Content
$InStuff = #'
IP-MIB::ipNetToMediaPhysAddress.13600001.10.4.48.1 = STRING: 36:b:7:0:41:31
IP-MIB::ipNetToMediaPhysAddress.13600001.10.4.49.21 = STRING: 3b:fa:a2:us:74:d9
IP-MIB::ipNetToMediaPhysAddress.13600001.10.3.50.22 = STRING: 3b:fa:a2:us:7b:f3
'# -split [environment]::NewLine
$Results = foreach ($IS_Item in $InStuff)
{
$Null = $IS_Item -match '\.\d{8}\.(?<IPv4>.+) = .+: (?<MacAddress>.+)$'
[PSCustomObject]#{
IPv4 = $Matches.IPv4
MacAddress = $Matches.MacAddress
}
}
$Results
you can use Export-CSV to send that to a nicely structured CSV file.

Related

Powershell - How to split a string based on characters?

I have a list of pdf filenames that need to be parsed and ultimately sent to a sql table, with the parse out pieces each in their own column. How would I split based on a dash '-' and ultimately get it into a table.
What cmdlets would you start with to split on a character? I need to split based on the dash '-'.
Thanks for the help.
Example File Names:
tester-2458-full_contact_snapshot-20200115_1188.pdf
tester-2458-limited_contact_snapshot-20200119_9330.pdf
Desired Results:
There is also a -split operator.
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_split
basic example:
if you have file names in $FilePaths array.
foreach($filepath in $FilePaths)
{
$parts = $filepath -split '-';
[pscustomobject]#{"User" = $parts[0]; "AppID" = $parts[1]; "FileType" = $parts[2]; "FilePath"=$filepath }
}
Use $variable.split('-') which will return a string array with a length equal to however many elements are produced by the split operation.
yet another way is to use regex & named capture groups. [grin]
what it does ...
creates a set of file name strings to work with
when ready to use real data, remove the entire #region/#endregion block and use either (Get-ChildItem).Name or another method that gives you plain strings.
iterates thru the collection of file name strings
uses $Null = to suppress the False/True output of the -match call
does a regex match with named capture groups
uses the $Match automatic variable to plug the captured values into the desired properties of a [PSCustomObject]
sends that PSCO out to the $Results collection
displays that on screen
sends it to a CSV for later use
the code ...
#region >>> fake reading in a list of file names
# in real life, use (Get-ChildItem).Name
$InStuff = #'
tester-2458-full_contact_snapshot-20200115_1188.pdf
tester-2458-limited_contact_snapshot-20200119_9330.pdf
'# -split [System.Environment]::NewLine
#endregion >>> fake reading in a list of file names
$Results = foreach ($IS_Item in $InStuff)
{
$Null = $IS_Item -match '^(?<User>.+)-(?<AppId>.+)-(?<FileType>.+)-(?<Date>.+)\.pdf$'
[PSCustomObject]#{
User = $Matches.User
AppId = $Matches.AppId
FileType = $Matches.FileType
Date = $Matches.Date
FileName = $IS_Item
}
}
# display on screen
$Results
# send to CSV file
$Results |
Export-Csv -LiteralPath "$env:TEMP\JM1_-_FileReport.csv" -NoTypeInformation
output to screen ...
User : tester
AppId : 2458
FileType : full_contact_snapshot
Date : 20200115_1188
FileName : tester-2458-full_contact_snapshot-20200115_1188.pdf
User : tester
AppId : 2458
FileType : limited_contact_snapshot
Date : 20200119_9330
FileName : tester-2458-limited_contact_snapshot-20200119_9330.pdf
content of the C:\Temp\JM1_-_FileReport.csv file ...
"User","AppId","FileType","Date","FileName"
"tester","2458","full_contact_snapshot","20200115_1188","tester-2458-full_contact_snapshot-20200115_1188.pdf"
"tester","2458","limited_contact_snapshot","20200119_9330","tester-2458-limited_contact_snapshot-20200119_9330.pdf"

Parse MDT Log using PowerShell

I am trying to setup a log which would pull different information from another log file to log assets build by MDT using PowerShell. I can extract a line of log using simple get-content | select-string to get the lines i need so output looks like that
[LOG[Validate Domain Credentials [domain\user]]LOG]!
time="16:55:42.000+000" date="10-20-2017" component="Wizard"
context="" type="1" thread="" file="Wizard"
and I am curious if there is a way of capturing things like domain\user, time and date in a separate variables so it can be later passed with another data captured in a similar way in output file in a single line.
This is how you could do it:
$line = Get-Content "<your_log_path>" | Select-String "Validate Domain Credentials" | select -First 1
$regex = '\[(?<domain>[^\\[]+)\\(?<user>[^]]+)\].*time="(?<time>[^"]*)".*date="(?<date>[^"]*)".*component="(?<component>[^"]*)".*context="(?<context>[^"]*)".*type="(?<type>[^"]*)".*thread="(?<thread>[^"]*)".*file="(?<file>[^"]*)"'
if ($line -match $regex) {
$user = $Matches.user
$date = $Matches.date
$time = $Matches.time
# ... now do stuff with your variables ...
}
You might want to build in some error checking etc. (e.g. when no line is found or does not match etc.)
Also you could greatly simplify the regex if you only need those 3 values. I designed it so that all fields from the line are included.
Also, you could convert the values into more appropriate types, which (depending on what you want to do with them afterwards) might make handling them easier:
$type = [int]$Matches.type
$credential = New-Object System.Net.NetworkCredential($Matches.user, $null, $Matches.domain)
$datetime = [DateTime]::ParseExact(($Matches.date + $Matches.time), "MM-dd-yyyyHH:mm:ss.fff+000", [CultureInfo]::InvariantCulture)

Powershell move output of loop into Array

It seems like a simple answer but for the life of me I cant figure it out. What I am trying to do is get a bunch of email addresses out of a text file and strip out the bit of the email past the # (e.g if the email address was adam#home.com I am interested in the adam bit).
The script below outputs the values that I want however I would like to have the output written into a array rather than to the console. What would be the best way of doing this?
Code below, thanks.
# Import the text file into a variable
$import = Get-Content c:\\temp\test.txt
# Variable to hold total number of emails
$totalEmails = $import.Count
#Variable to run loop
$start = 0
#Used as a separator to look at the first part of the email address
$separator = "#"
# Will increment by two to show the first part of the array in parts which holds the text before the #
$even = 0
# Username after #
$userName
#Strip out the text before the #
do {
$parts = $import.split($separator)
$even+=2
# This line here is whats not working, I would like to have the output of each echo written into the array $userName
$userName = echo $parts[$even]
$start++
} while ($totalEmails -gt $start)
Your email parsing doesn't make a whole lot of sense. Here's a one-liner for your question:
$Arr = #(Get-Content -Path 'C:\temp\test.txt') -replace '#.+'

Powershell to read some strings from each line

I have a requirement like:
Have a text file containing the following in the following pattern
172.26.xxy.zxy:Administrator:Password
172.26.xxy.yyx:Administrator:Password
172.26.xxy.yyy:Administrator:Password
172.26.xxy.yxy:Administrator:Password
I need my powershell script to read each word and use that word whereever required. For example,
foreach(something)
{
I want the IP's(172.26.---.---) to read and store the value as a variable.
I want to store the two words after **:** in seperate variables.
}
How can this be done? I know to read an entire file or get some specific string. But I need the same to be done on each line.Any help would be really appreciated.
Something like this? You can just split on the : and then store your variables based on the index
$contents = Get-Content C:\your\file.txt
foreach($line in $contents) {
$s = $line -split ':'
$ip = $s[0]
$user = $s[1]
$pass = $s[2]
write-host $ip $user $pass
}
minor edit: "t" missing in content.
You can write a regular expression to replace to remove the parts you do not need
$ip_address= '172.26.xxy.zxy:Administrator:Password' -replace '^(.+):(.+):(.+)$','$1'
$user= '172.26.xxy.zxy:Administrator:Password' -replace '^(.+):(.+):(.+)$','$2'
$pwd= '172.26.xxy.zxy:Administrator:Password' -replace '^(.+):(.+):(.+)$','$3'
I think the more generic and pure Powershell way would be something like this:
Select-String "(.*):(.*):(.*)" c:\file.txt |
Select #{Name="IP"; Expression = {$_.Matches.Groups[1]}},
#{Name="User"; Expression = {$_.Matches.Groups[2]}},
#{Name="Password"; Expression = {$_.Matches.Groups[3]}}
The Output would be then an array of objects each having three properties IP, User and Password. So you can now use them for your purposes, or just add more commands at the end of the pipe.

Read a Csv file with powershell and capture corresponding data

Using PowerShell I would like to capture user input, compare the input to data in a comma delimited CSV file and write corresponding data to a variable.
Example:
A user is prompted for a “Store_Number”, they enter "10".
The input, “10” is then compared to the data in the first position
or column of the CSV file.
Data, such as “District_Number” in the corresponding position /
column is captured and written to a variable.
I have gotten this method to work with an Excel file (.xlsx) but have found it to be terribly slow. Hoping that PowerShell can read a CSV file more efficiently.
Link to an example CSV file here:
Store_Number,Region,District,NO_of_Devices,Go_Live_Date
1,2,230,10,2/21/2013
2,2,230,10,2/25/2013
3,2,260,12,3/8/2013
4,2,230,10,3/4/2013
5,2,260,10,3/4/2013
6,2,260,10,3/11/2013
7,2,230,10,2/25/2013
8,2,230,10,3/4/2013
9,2,260,10,5/1/2013
10,6,630,10,5/23/2013
What you should be looking at is Import-Csv
Once you import the CSV you can use the column header as the variable.
Example CSV:
Name | Phone Number | Email
Elvis | 867.5309 | Elvis#Geocities.com
Sammy | 555.1234 | SamSosa#Hotmail.com
Now we will import the CSV, and loop through the list to add to an array. We can then compare the value input to the array:
$Name = #()
$Phone = #()
Import-Csv H:\Programs\scripts\SomeText.csv |`
ForEach-Object {
$Name += $_.Name
$Phone += $_."Phone Number"
}
$inputNumber = Read-Host -Prompt "Phone Number"
if ($Phone -contains $inputNumber)
{
Write-Host "Customer Exists!"
$Where = [array]::IndexOf($Phone, $inputNumber)
Write-Host "Customer Name: " $Name[$Where]
}
And here is the output:
Old topic, but never clearly answered. I've been working on similar as well, and found the solution:
The pipe (|) in this code sample from Austin isn't the delimiter, but to pipe the ForEach-Object, so if you want to use it as delimiter, you need to do this:
Import-Csv H:\Programs\scripts\SomeText.csv -delimiter "|" |`
ForEach-Object {
$Name += $_.Name
$Phone += $_."Phone Number"
}
Spent a good 15 minutes on this myself before I understood what was going on. Hope the answer helps the next person reading this avoid the wasted minutes!
(Sorry for expanding on your comment Austin)
So I figured out what is wrong with this statement:
Import-Csv H:\Programs\scripts\SomeText.csv |`
(Original)
Import-Csv H:\Programs\scripts\SomeText.csv -Delimiter "|"
(Proposed, You must use quotations; otherwise, it will not work and ISE will give you an error)
It requires the -Delimiter "|", in order for the variable to be populated with an array of items. Otherwise, Powershell ISE does not display the list of items.
I cannot say that I would recommend the | operator, since it is used to pipe cmdlets into one another.
I still cannot get the if statement to return true and output the values entered via the prompt.
If anyone else can help, it would be great. I still appreciate the post, it has been very helpful!