Keep DC part of distinguished name - powershell

I have for input distinguished names like the following:
CN=A00.user,OU=MyOU,OU=A00,OU=MyOU3,DC=my,DC=domain
CN=A01.user1,OU=MyOU1,OU-MyOU2,OU=A00,OU=MyOU3,DC=my,DC=first,DC=domain
I need to print only the DC part, to get an output like:
my.domain
my.first.domain
Looks like split or replace should work, but I'm having trouble figuring out the syntax.

You can use Get-ADPathname.ps1 with the -Split parameter, Select-String with a regular expression, and the -join operator:
(
Get-ADPathname 'CN=A01.user1,OU=MyOU1,OU-MyOU2,OU=A00,OU=MyOU3,DC=my,DC=first,DC=domain' -Split | Select-String '^DC=(.+)' | ForEach-Object {
$_.Matches[0].Groups[1].Value
}
) -join '.'
Output:
my.first.domain

Here's a quick and dirty way to get it done.
("CN=A00.user,OU=MyOU,OU=A00,OU=MyOU3,DC=my,DC=domain " -split "," |
Where-Object { $_.StartsWith("DC=") } |
ForEach-Object { $_.Replace("DC=","")}) -join "."
Produces
my.domain

I would simply remove everything up to and including the first ,DC= and then replace the remaining ,DC= with dots.
$dn = 'CN=A00.user,OU=MyOU,OU=A00,OU=MyOU3,DC=my,DC=domain',
'CN=A01.user1,OU=MyOU1,OU-MyOU2,OU=A00,OU=MyOU3,DC=my,DC=first,DC=domain'
$dn -replace '^.*?,dc=' -replace ',dc=', '.'

Related

Filter list of files using an array of regular expressions (regex)

How can I change this so that I can cycle through a list of files and compare them all to an array of regular expressions?
$Regex_FileList = #"
TestFile_53-1227.txt^Home/Client/
Testfile_R-122719.txt^Home/Client/
TestingAFile1219.csv^Home/Client/
Test_PMT_122719.txt^Home/Client/
This_is_a_TEST_122719.txt^Home/folder/
"#
$Regex_1 = "^TestFile_R-\d{1,6}"
$Regex_2 = "This_is_a_TEST_\d{1,6}\.txt"
$Regex_3 = "^Test_NB"
$Regex_Array = #($Regex_1,$Regex_2,$Regex_3)
[array]$files = $Regex_FileList -split '\r?\n'
$files = $files | Where-Object {$_} #filter out empty array vals
$finalfiles = #()
for($i;$i -lt $files.count;$i++){
$finalfiles = $files | Where {$_ -notmatch $Regex_Array[$i]}
}
$finalfiles
I believe my problem is this particular line: $finalfiles = $files | Where {$_ -notmatch $Regex_Array[$i]}
If I do something like $files | Where {$_ -notmatch "^This"} of course the regex works, it takes This_is_a_TEST_122719.txt^Home/folder/ out of my $Regex_FileList. If I change it back to using $Regex_Array[$i] then the $finalfiles variable ends up blank.
I also tried this instead of the for loop $files | ForEach-Object { if($_ -notmatch $Regex_Array){$finalfiles += $_} }
Another thing I tried:
for($i;$i -lt $Regex_FileList.count;$i++){
foreach($regex in $Regex_FileList){
if($files[$i] -notmatch $_){
$finalfiles += $files[$i]
}
}
}
Another pretty simple way. All you need is the comma operator to make arrays. The line property from select-string has the actual string result.
$FileList = 'TestFile_53-1227.txt^Home/Client/',
'Testfile_R-122719.txt^Home/Client/',
'TestingAFile1219.csv^Home/Client/',
'Test_PMT_122719.txt^Home/Client/',
'This_is_a_TEST_122719.txt^Home/folder/'
$PatternList = '^TestFile_R-\d{1,6}',
'This_is_a_TEST_\d{1,6}\.txt',
'^Test_NB'
$filelist | select-string -notmatch $patternlist | foreach line
# output
TestFile_53-1227.txt^Home/Client/
TestingAFile1219.csv^Home/Client/
Test_PMT_122719.txt^Home/Client/
the problem seems to be the overly convoluted steps you chose to take. when i run your code on win7ps5.1, i get the following error ...
Index operation failed; the array index evaluated to null.
At line:25 char:35
+ $finalfiles = $files | Where {$_ -notmatch $Regex_Array[$i]}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
i cannot understand your logic, so i gave up on that. [blush]
here is how i would find the strings that DO NOT match your regex pattern list ...
what it does ...
builds a here-string, splits it into lines, and puts the results into an array
builds a regex pattern list
converts that pattern list into a regex OR structure by joing the items with | [the regex OR symbol]
runs -notmatch against the input list using the regex pattern
stores that in $NonMatches
displays it on the screen
the code ...
$Regex_FileList = #"
TestFile_53-1227.txt^Home/Client/
Testfile_R-122719.txt^Home/Client/
TestingAFile1219.csv^Home/Client/
Test_PMT_122719.txt^Home/Client/
This_is_a_TEST_122719.txt^Home/folder/
"# -split [System.Environment]::NewLine
$PatternList = #(
'^TestFile_R-\d{1,6}'
'This_is_a_TEST_\d{1,6}\.txt'
'^Test_NB'
)
$RegexPatterList = $PatternList -join '|'
$NonMatches = $Regex_FileList -notmatch $RegexPatterList
$NonMatches
output ...
TestFile_53-1227.txt^Home/Client/
TestingAFile1219.csv^Home/Client/
Test_PMT_122719.txt^Home/Client/

Splitting in Powershell

I want to be able to split some text out of a txtfile:
For example:
Brackets#Release 1.11.6#Path-to-Brackets
Atom#v1.4#Path-to-Atom
I just want to have the "Release 1.11.6" part. I am doing a where-object starts with Brackets but I don't know the full syntax. Here is my code:
"Get-Content -Path thisfile.txt | Where-Object{$_ < IM STUCK HERE > !
You could do this:
((Get-Content thisfile.txt | Where-Object { $_ -match '^Brackets' }) -Split '#')[1]
This uses the -match operator to filter out any lines that don't start with Brackets (the ^ special regex character indicates that what follows must be at the beginning of the line). Then it uses the -Split operator to split those lines on # and then it uses the array index [1] to get the second element of the split (arrays start at 0).
Note that this will throw an error if the split on # doesn't return at least two elements and it assumes that the text you want is always the second of those elements.
$bracketsRelease = Get-Content -path thisfile.txt | foreach-object {
if ( $_ -match 'Brackets#(Release [^#]+)#' )
{
$Matches[1]
}
}
or
(select-string -Path file.txt -Pattern 'Brackets#(Release [^#]+)#').Matches[0].Groups[1].value

powershell split keeping only the 2 first part of string

i'm new in powershell
i have a file that contains OU paths separates by "/"
i'd like to only keep the 2 first element of each string
example:
paris/sales/salers/14tharrdt
london/comptability/office1
would give
paris/sales
london/comptability
i googled and found many things, but no way to do this simple thing
thanks for help
You could use -split to split the string on the \ character, select the first two elements and join them together:
$content = Get-Content 'your_file_path'
$content | foreach {
($_ -split '/')[0, 1] -join '/'
}
$content | Set-Content 'your_file_path'
Or, if you prefer using regex here a solution without split (demo here):
$content = Get-Content 'your_file_path'
$content | foreach {
$_ -replace '(.*?\/[^\/]+).*', '$1'
}
$content | Set-Content 'your_file_path'
Like:
$a = "paris/sales/salers/14tharrdt"
$b = $a.Split("/")[0] + "/" + $a.Split("/")[1]
$b
Improvement would be if call Split once and save it to a variable

csv reformatting with powershell

I have a file cointaining a lot of lines in this format:
firstname ; lastname ; age ;
(it's a bit more complex but that's basically the file)
so the fields are of a fixed length, padded with spaces and with a semicolon in between the fields.
I would like to have it so:
firstname, lastname, age,
(commas and no fixed width)
I have replaced the commas with regexp but I would like to also trim the end of the strings. But I don't know how to do this.
The following is my start, but I can't manage to get a ".TrimEnd()" in there. I have also thought of trying a "-replace(" ", " ") but I can't integrate it in this expression:
Get-Content .\Bestand.txt | %{$data= [regex]::split($_, ';'); [string]:: join(',', $data)}
Can I get some information on how to achieve this?
I suggest you replace each occurrence of 'space;space' with a comma (assuming the replaced characters do not appear within a valid value), so the end result will look like:
firstname,lastname,age
Keeping it like the following is not a good idea cause now some of your headers (property names) start with a space:
"firstname, lastname, age,"
Give this a try (work on a copy of the file):
(Get-Content .\Bestand.txt) |
foreach {$_ -replace ' ; ',','} |
out-file .\Bestand.txt
Now it's easy to import and process the file with Import-Csv cmdlet.
The -replace operator takes a regular expression, which you can use to remove all leading and trailing spaces:
Get-Content .\Bestand.txt |
Foreach-Object { $_ -replace ' *; *',',' } |
Out-File .\Bestand.csv -Encoding OEM
Since you already create something CSV-ish, I'd go all the way and create proper CSV:
$cols = "firstname","lastname","age","rest"
Import-Csv "C:\input.txt" -Delimiter ";" -Header $cols | % {
foreach ($property in $_.PsObject.Properties) {
$property.Value = ([string]$property.Value).Trim()
}
$_
} | Export-Csv "C:\output.csv" -NoTypeInformation

Powershell: Find and replace words split by newline

So I have a text file that looks something like this:
Members : {USER\member1, USER\member2, US
ER\member3, USER\member4, USER
\member5, USER\member6}
and I would like to remove USER\. The following code removes it but not when it's split by a newline, for example when US on one line and ER\ on another line.
Foreach-Object { %{$_.Replace('USER\', '') }
Putting `n or `r in there doesn't work. Any help is appreciated.
Try this:
PS > ((Get-Content .\t.txt) | % { $_.Trim() }) -join "" -replace "USER\\"
Members : {member1, member2, member3, member4, member5, member6}
If the text is in a string-array, switch out (Get-Content .\t.txt) with your variable. If you have the text in a string(not array) variable, use:
($MYSTRINGVAR.Split("`r`n") | % { $_.Trim() }) -join "" -replace "USER\\"
EDIT Just modify the "Members" part:
$text = (Get-Content .\input.txt) -join "`r`n"
($text | Select-String '(?s)(?<=Members : \{)(.+?)(?=\})' -AllMatches).Matches | % {
$text = $text.Replace($_.Value, ($_.Value -split "`r`n" | % { $_.Trim() }) -join "" -replace "USER\\")
}
$text | Set-Content output.txt
There are probably easier ways to get there, but you can give this one a try:
$Text = #'
Members : {USER\member1, USER\member2, US
ER\member3, USER\member4, USER
\member5, USER\member6}
'#
# First - USER\ with newline inside..
foreach ($index in 1..4) {
$Text = $Text -replace ('USER\\'.Insert($index,'(\r\n\s+)')), '$1'
}
# Than - pure USER\
$Text = $Text -replace 'USER\\'
$Text
As you can see I create few patterns that contain and keep that element in results (, '$1'). For simple ones - I just remove USER\
I've used herestring to create text to work with, it's possible that \r may not be needed for actual file.
This is actually just a comment to Graimer's solution, but it would've been too long and also not readable enough as a comment, so I'm making it a (supplementary) answer instead.
To re-wrap the string after removing USER\ you could do something like this:
$s = "Members : {member1, member2, member3, member4, member5, member6}"
$s -match '^(.*?{)(.*)(})$'
$pad = " " * $matches[1].Length
$matches[1] + ($matches[2] -replace '(.{1,20},) ', "`$1`r`n$pad") + $matches[3]
The first regular expression splits the string into 3 parts that can be accessed via the $matches collection:
Name Value
---- -----
3 }
2 member1, member2, member3, member4, member5, member6
1 Members : {
0 Members : {member1, member2, member3, member4, member5, member6}
$matches[1] is the prologue including the opening curly bracket, $matches[2] is the member list, and $matches[3] is the closing curly bracket. Now you only need to wrap $matches[2] at whatever length you want:
'(.*{1,20},) '
The above means "longest match of at most 20 characters followed by a comma and a space". Replace that with the 1st group ($1) followed by a line-break (```rn``) and a number of spaces that matches the length of the prologue ($pad`) and glue it back together with prologue and trailing curly bracket.