Powershell: combine contents of strings with dots inbetween, ignore empty ones - powershell

Our naming convention consists of the first name, insertion, and lastname, all separated by dots. An example:
Stack Overflow = Stack.Overflow
Stack over Flow = Stack.over.flow
These outputs will be used later on in the script for the creation of a mailbox, user account, etc.
I've successfully combined the values of all strings by simply plus-ing them together, like this:
$Convention = $Firstname+"."+$Insertion+"."+$LastName
The values for these strings come from information being put in when the stript runs (Read-Host "....")
Now, I'm struggling with making this more dynamic. Of course, not every person has an insertion in their name. Using the given example, the current output of $Convention would be "Stack..Overflow", instead of "Stack.Overflow".
My question to you is: how can I filter out both, the $Insertion and the extra dot, when $Insertion is empty? It's most likely something very simple, but I can't seem to figure out what it is.
Thanks in advance for any given help!
Kr,
Robbert

I would do
$Convention = ('{0}.{1}.{2}' -f $Firstname, $Insertion, $LastName) -replace '\.+', '.'
The -replace uses regex in the first parameter, so '\.+', '.' means to replace 1 or more consecutive dots by a single dot.
Alternatively you could use regex \.{2,} which reads two or more consecutive dots
Example:
$Firstname = 'Robbert'
$Insertion = ''
$LastName = 'Verwaart'
$Convention = ('{0}.{1}.{2}' -f $Firstname, $Insertion, $LastName) -replace '\.+', '.'
Output:
Robbert.Verwaart

The code below will go through each of your $convention array, if this is an array, and test if the insertion is empty. If the $Insertion variable is empty, the $i will remove the $Insertion variable and the extra .. You need to add this into the script as a test, before creating the mailboxes.
foreach ($i in $convention){
if($insertion -eq "" -or $insertion -eq $null) {
$i= $Firstname+"."+$LastName
} else {
continue
}
}

Related

From output, include line only contain a key word and extract first field from the included lines with powershell

With PowerShell, I am trying to extract the first field from an output that contains multiple lines as below. Along with this, I wanted to exclude if the line doesn't have a key 'web:'
Getting apps in org SomeOrg / space Somespace as x-user...
name requested state processes routes
maskedappname1 started web:1/1 maskedappname1.com
maskedappname2 started web:0/1 maskedappname2.com
maskedappname3 started web:1/1 maskedappname3.com
maskedappname4 started web:1/1 maskedappname4.com
maskedappname5 started web:1/1 maskedappname5.com
maskedappname6 stopped web:0/1 maskedappname6.com
after execution, my final output should be
maskedappname1
maskedappname2
maskedappname3
maskedappname4
maskedappname5
maskedappname6
tried multiple ways didn't help me.
Much appreciate it if I get some help on this.
Thanks.
You can use a switch with the -Regex parameter to match any line having web: and capture the everything from the beginning of the line until the first whitespace.
switch -File path\to\file.ext -Regex {
'(^\S+).+web:' { $Matches[1] }
}
See https://regex101.com/r/fxQtcN/1 for details.
iterate through each line
$array = $textWithMultipleLines.Split(ā€œ`nā€)
foreach ($line in $array){
# ...
}
take fixed length (if possible) or split on space ant take the first item of the split array
($extract -split " ")[0]
# or the regex way:
$extract -replace '^([^ ]+ ).+$','$1'
all together
$array = $textWithMultipleLines.Split(ā€œ`nā€)
foreach ($line in $array){
$maskedAppName = ($line -split " ")[0]
Write-Host "maskedAppName: $maskedAppName"
}

Powershell Script needed to redact items in between separators in a row according to defined list

Hello and thanks for reading. It's my first post and really need some help. The hardest part is getting my question across in a way that people will understand. I will try my best.
I have some huge csv files (some in excess of 8 millions rows so Excel not an option really) where I need to modify the contents of the 3rd 'field' in each row according to sets of words defined in a reference file
So an example csv might be something like:
AB12|TEST|CAT DOG MOUSE|TEST1|TEST2|TEST3||TEST4
CD34|TEST|HORSE CART TRAIN|TEST1|TEST2|TEST3||TEST4
etc etc.
In my reference file I have a list eg:
CAT
HORSE CART
These are contained in a CSV
What I need is to modify the files so that the 3rd 'field' (everything after the 2nd'|' and before the 3rd '|' is compared to the reference list and modified to match. ie in the first line, everything after CAT would be deleted and in the second line, everything after HORSE CART would be deleted within this 3rd field. So the resultant file outputted would look like:
AB12|TEST|CAT|TEST1|TEST2|TEST3||TEST4
CD34|TEST|HORSE CART|TEST1|TEST2|TEST3||TEST4
I normally use F.A.R.T to modify large files, but this needs to be a bit more clever than FART is able to offer.
I really hope this makes sense to someone out there and appreciate any help you might offer.
So far I have been experimenting with this, but it's a long way off doing what I want:
cls
$content = ""
write-output "** Original String **"
write-output ""
$content = Get-Content "~\Desktop\Test\*.dat"
$content
$separator1 = " "
$separator2 = "|"
$parts = $content.split($separator1)
write-output ""
write-output "** Revised String **"
write-output ""
$part1 = echo $parts[0]
$part3 = $part2.split($separator2)
$part4 = $part3[1]
$revised = $part1, $part4 -join "|"
$revised
write-output ""
So in summary then: This is really a modified 'Find and Replace Text' function that concentrates on a single field in each line, looks for matching sets of words, then deletes everything in that field other than the matched words, which are defined in a separate csv file.
Ok, as comparing arrays in PowerShell doesn't support wild cards we have to do this the old fashioned (costly) way. Compare every field with every reference.
I've not provided an example of reading the file as that can be done in different ways with regards to speed or memory consumption (your choice).
Also, I've provided the reference as an array instead as a file input to keep the example to the point (and easily testable).
The output should then of course be done to a new file instead of written to the host.
$file = #"
F1|F2|F3|F4|F5|F6|F7|F8
AB12|TEST|CAT DOG MOUSE|TEST1|TEST2|TEST3||TEST4
CD34|TEST|HORSE CART TRAIN|TEST1|TEST2|TEST3||TEST4
CD34|TEST|HORSE CART|TEST1|TEST2|TEST3||TEST4
"#
$ref = #("CAT*","HORSE CART*")
$file.split("`n") | foreach {# line in file
$outline = $nul
$_.split('|') | foreach {# field in the line
$field = $_
$refhit = $false
$ref | foreach {# item in the ref array
if ($field -like $_) {# replace field with ref
$refhit = $true
$outline += $_.TrimEnd('*') + '|'
}# end match
}# end ref
if (!$refhit){#pass on the field as is
$outline += "$field|"
}
}#end field
# Output filtered line
write-host $outline.TrimEnd('|')
}#end line

Powershell search and replace part of a string

I have a file with the following content:
123
456
789
XYZ
ABC999XXXXXXX
I need to search the file for 3 numeric characters, and replace the first and third character based on user input. If the user inputs character 1 = 0 and character 3 = 9, I need to return.
029
059
089
I'm trying to do this with a simple search and replace, without creating a variable for each character. Also of note, I need to search for the criteria of 3 numbers, discarding the alpha character rows.
Please Note: This is a simplified version of what I need to do. The situation is long with many more fields but I hope that boiling this down will give me something that I can work with. Thanks in advance.
Assuming that the conditions are as you've described, the -replace operation suggested in the comment should do just what you want.
All you need to do is take user input and interpolate it into the replace string, exemplified below:
# Get user input for the first digit
do{
$a = Read-Host -Prompt "Input 1st digit"
} while ($a -notmatch "^\d$")
# Get user input for the third digit
do{
$b = Read-Host -Prompt "Input 3rd digit"
} while ($b -notmatch "^\d$")
# pattern that matches exactly 3 digits, captures the middle one
$pattern = "^\d(\d)\d$"
# replacement consisting of the user input and a reference to the capture group
$replace = "$a{0}$b" -f '${1}'
# Let's replace!
$InputObject = Get-Content "C:\my\file\path.txt"
$InputObject -replace $pattern,$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.

Count number of spaces, and split at the last one

I have a string simliar to:
c:/folder name/somewhere/application.exe instanceName
(n.b. the space in "folder name" is intentional) I need a way to split this into:
[0]c:/folder name/somewhere/application.exe
[1]instanceName
I was going to use split-path, but apparently there is a bug in powershell v2 that stops me doing this:
Split-Path : Cannot find drive. A drive with the name '
So, I figured if I count how many spaces there are, and then simply use -split() to split it at the last space.
But, I can't see how to count the number of spaces.
I've found lots of examples that talk about using regex to count complex strings, but I just want to count spaces!
Tonnes of ways to do this I imagine but to use your split idea you could do the following.
$split = "c:/folder name/somewhere/application.exe instanceName".Split(" ")
$path = $split[0..($split.count -2)] -Join " "
$instance = $split[-1]
Split the sting by spaces. The number of spaces is represented by the count of strings in the array $split. We join all the strings in the array accept the last intp $path then we take the last entry and assign it to $instance
You could also use .substring and .lastindexof
$string = "c:/folder name/somewhere/application.exe instanceName"
$index = $string.LastIndexOf(" ")
$string.Substring(0,$index)
$string.Substring($index + 1)
I can't see a way to split this directly into an array at this time but outputing as an array would not be a big deal.
$path, $instance
or
$array = #($path,$instance)
You can use a regular expression for this:
$s = "c:/folder name/somewhere/application.exe instanceName"
$s -match '(.*) (.*)$'
$matches[1]
$matches[2]
The special variable $matches is populated if the -match operation is true.
$matches[0] contains the original string, and other indexes will exist for the number of groups (patterns in parenthesis) in the regex. In this case: (.*) (.*)$ we have two groups.