How to remove specific text from extensionattribute - regex

Task is to remove |text from an extension attribute but, but leave the rest of the text there.
I’ve tried the below but it does not remove it.
Set-ADUser -identity user -Clear #{extensionAttribute1="|text"}

Set-ADUser -identity user -Remove #{extensionAttribute1="|text"}

Set-ADUser -identity user -Replace #{extensionAttribute1='|text',''}
Current string have multiple | characters that needs to remain.
Example. Some|unrelated|text&whatever
Need to remove just |text
Remain: Some|unrelated&whatever

You need to get the old value first, manipulate it however you want, and then set it back on the object. Something like this should work:
$oldValue = (Get-ADUser -Identity user -Properties extensionAttribute1).extensionAttribute1
$newValue = $oldValue.Replace('|text', [string]::Empty)
Set-ADUser -Identity user -Replace #{extensionAttribute1=$newValue}

Related

Powershell Compare value to multiple arrays

I am trying to compare data to multiple sources and then give me a report of the errors. Due to the changing nature of exceptions, I wanted to build an exception table in csv format that I can change on the fly.
I am going to give the data the best I can and show you what I'm trying to achieve and show you where I'm coming into problems.
The exceptions list holds the prefix to different types of accounts:
Exceptions List
_______________
FQ
Q
HQ
E
So if my Account was BND123 then I may have an account called FQBND123 or QBND123 I want to be able to add to this list if one of the teams decides they need to make a JQ account or anything like that in the future.
This is an example of Inventoryreport.csv I'm looking to parse:
Safe Target system user name
HUMAN_ABC QABC
HUMAN_CDE QCDE
HUMAN_FGHIJ QFGHIJ
HUMAN_P123456 root
HUMAN_KLMNO QKLMNO1
HUMAN_P789123 FQ789123
So I am looking to compare target system username to the safe name, and if the leading account is in the exception list, it passes it up, and if it does not, then it throws it as an error.
So in the case of the data above the 2 rows would throw an error below.
HUMAN_P123456 root
HUMAN_KLMNO QKLMNO1
Root for obvious reason and the KLMNO account because of the trailing 1.
The problem I am getting is that it is saying everything is an error. If I hand type it in to the loop everything is fine.
I had the exceptions in a foreach loop too inside the one for the inventory, but it keep looping over the same results and still spitting out everything.
Hopefully this is an OK explanation, I'm sure I'm making this harder than it needs to be.
$loc = $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$D = $loc + "\Exceptions\Exceptions.csv"
$E = $loc + "\Import\InventoryReport.csv"
$exceptions = Import-Csv -LiteralPath $D
$inventory = Import-Csv -LiteralPath $E
$list2 = 'Inventory Report Exceptions'
$list3 = 'Target system user name'
$DO = $loc + "\Report\Inventory Report Errors" + "$((Get-Date).ToString('MM-dd-yyyy')).CSV"
$time = (Get-Date).ToString()
foreach ($item in $inventory) {
$input1 = $item.Safe -replace "HUMAN_"
$input4 = $item.Safe -replace "HUMAN_P"
$input2 = $item.$list3
$input3 = $item.Safe
if ($input2 -eq ($exceptions.$list2 + $input1) -or $input2 -eq ($exceptions.$list2 + $input4)) {
return
}
else {
$newitem = New-Object -TypeName PSCustomObject -Property #{
Safe = $input1
Owner = $input2
}| Export-CSV -LiteralPath $DO -NoTypeInformation -append
}
}
Your question is a bit long and not very clear...
Let's look if I got it right:
I shortened the exceptions list to a regular expression anchored at begin
simulate the inventory.csv with a here string
append a column Pass to that
iterate the entries comparing the split'ed values for equality and save in the new col.
## Q:\Test\2018\11\02\SO_53109141.ps1
$Inventory = #"
Safe,Target system user name
HUMAN_ABC,QABC
HUMAN_CDE,QCDE
HUMAN_FGHIJ,QFGHIJ
HUMAN_P123456,root
HUMAN_KLMNO,QKLMNO1
HUMAN_P789123,FQ789123
"# | ConvertFrom-Csv
#$Exception = [regex]'^(FQ|Q|HQ|E)'
$Exception = [RegEx]("^("+((Import-Csv .\exceptions.csv).'Exceptions List' -join '|')+")")
$Fail = $Inventory | Select-Object *,Pass | ForEach-Object {
if ( ($_.Safe -split '_P?')[1] -ne ($_.'Target system user name' -split $Exeption)[2]){
[PSCustomObject]#{
Safe = ($_.Safe -split '_')[1]
Owner= $_.'Target system user name'
}
}
}
$Fail | Export-Csv '.\new.csv' -NoTypeInformation
Sample output:
Safe Target system user name Pass
---- ----------------------- ----
HUMAN_ABC QABC True
HUMAN_CDE QCDE True
HUMAN_FGHIJ QFGHIJ True
HUMAN_P123456 root False
HUMAN_KLMNO QKLMNO1 False
HUMAN_P789123 FQ789123 True
EDIT you can read in the exception from a file:
> import-csv .\exceptions.csv
Exceptions List
---------------
FQ
Q
HQ
E
And build a RegEx from the content:
$Exception = [RegEx]("^("+((Import-Csv .\exceptions.csv).'Exceptions List' -join '|')+")")

RegEx Finding multiple matches with a quantifier

I have this PowerShell code:
$uri = "http://charts.spotify.com/api/tracks/most_streamed/au/daily/latest"
$ContentType = "application/json"
$postblog = (Invoke-WebRequest -Uri $uri).Content -match 'track_name\S:\S(.*?)",'
$matches[1]
When I run this, I get this result:
FourFiveSeconds
Problem is, I know there are more songs than just this one song. And I know that the match I am using, the string of text "track_name" exists more than once. How can I change my RegEx so that it matches every match it can find? In other words, the expected output would be multiple matches, allowing me to list all the songs, e.g. $matches[1], $matches[2], $matches[3], $matches[4], etc.
Since you are using Invoke-WebRequest, I assume you are using Powershell v4.0. Therefore, you can use ConvertFrom-Json on the data received and iterate over it, instead of using a regex solution:
$uri = "http://charts.spotify.com/api/tracks/most_streamed/au/daily/latest"
$ContentType = "application/json"
$postblog = (Invoke-WebRequest -Uri $uri).Content | ConvertFrom-Json
Now, the entire tracks data is available inside $postblog.tracks array.
Iterate over them to get the track_urls:
Foreach( $track in $postblog.tracks ) {
Write-Output $track.track_url
}
EDIT
Apparently, you can simply use:
Write-Output $postblog.tracks.track_url
instead of the Foreach code-block. Thanks to #PetSerAl for that :)
Thanks to all, yes you are right, converting it to JSON gives me heaps more options and it is cleaner than using RegEx.
I have this script now, which should definitely do the trick.
$spotifytopsongs = #()
$uri = "http://charts.spotify.com/api/tracks/most_streamed/au/daily/latest"
$ContentType = "application/json"
$spotifyjson = (Invoke-WebRequest -Uri $uri).Content | ConvertFrom-Json
$spotifyjson.tracks | select -First 50 | % {$spotifytopsongs += #($_.artist_name + " - " + $_.track_name)}
cls;$spotifytopsongs

Using regex to validate email address in powershell

So i made a script that parses a .msg file in outlook and ommits the result. The whole scripts works except for when I receive an email from inside the network (we use Active Directory) is when i get a result similar to this: /O=Business/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=MIKEF
otherwise for emails outside the network I get email#email.com. I would like to to validate this this with regex that way it would take the name in the CN=" " and adds it to my #email.com
$MSGFILEPATH = '\\srv01\FTP\EmailtoSupportPortal\Testing'
$MSGCOMPLETED= '\\srv01\FTP\EmailtoSupportPortal\Testing\Completed'
Function MSGFiles {
Get-ChildItem $MSGFILEPATH -Filter *.msg|`
ForEach-Object{
$outlook = New-Object -comobject outlook.application
$msg = $outlook.CreateItemFromTemplate($_.FullName)
$body = $msg.Body
$SEM = $msg.SenderEmailAddress
$Subject = $msg.Subject
$SEM
}
}
MSGFiles
Check the MailItem.SenderEmailType property. If it is "EX", use MailItem.Sender.GetExchangeUser.PrimarySmtpAddress (be prepared to handle nulls/errors).
Otherwise use the SenderEmailAddress property the way you do that now.

Powershell -replace regex not working on connection strings

I'm attempting to use the Powershell -replace command to update the data source in my config file. However, the -replace regex below will not remove the $oldServer value.
I've place a string directly in to the $_.connectionString variable in the loop and it saved properly, so I know that is not the issue. Seems to just be the regex.
#environment variables
$env = "DEV"
$oldServer = "quasq10"
$newValue = "$env-AR-SQL.CORP.COM"
$doc = [xml](Get-Content "D:\AMS\app.config")
$doc.configuration.connectionStrings.add|%{
$_.connectionString = $_.connectionString -replace $oldServer, $newValue;
}
$doc.Save($file.FullName)
EDIT
Per the comment below I added a Write-host $_.connectionString statement as the first line in the loop. Below is the console output
metadata=res:///MonetDb.csdl|res:///MonetDb.ssdl|res://*/MonetDb.msl;provider=System.Data.SqlClient;provider connection string="data source=quasq10\sql08a;initial catalog=MyDB
;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"
I just put this right into ISE, I copied your connection string into a variable and was able to do this replace as a one off.
$connectionString = 'metadata=res:///MonetDb.csdl|res:///MonetDb.ssdl|res://*/MonetDb.msl;provider=System.Data.SqlClient;provider connection string="data source=quasq10\sql08a;initial catalog=MyDB ;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"'
$env = "DEV"
$oldServer = "quasq10"
$newValue = "$env-AR-SQL.CORP.COM"
$connectionString -replace $oldServer, $newValue
res:///MonetDb.csdl|res:///MonetDb.ssdl|res://*/MonetDb.msl;provider=System.Data.SqlClient;provider connection string="data source=DEV-AR-SQL.CORP.COM\sql08a;initial catalog=MyDB ;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"
I think your foreach loop might not be getting the info you want, because it looks like your replace is fine.
$doc.configuration.connectionStrings.add
I haven't done much with XML, does the XML data type have an ADD member function? You aren't really adding anything, right?
As a test, what do you get from this:
$doc.configuration.connectionStrings | % {
$_.connectionString -replace $oldServer, $newValue;
}
Run that against a dummy file and see what happens.
For a sanity check on the replace operator:
$string = "The quick brown fox jumped over the lazy dog"
$oldColor = "brown"
$newColor = "orange"
$string -replace $oldColor, $newColor
To avoid digging through comments, this method worked
$string.Replace($oldColor,$newColor)

How can I make a regex to find instances of the word Project not in square brackets?

For example:
$lang['Select Project'] = 'Select Project OK';
$lang['Project'] = 'Project';
I want to find only the instances of the word 'Project' not contained within the square brackets.
I'm using ColdFusion studio's extended replace utility to do a global replace.
Any suggestions?
Code Sample Follows:
<?php
$lang['Project Message Board'] = 'Project Message Board';
$lang['Project'] = 'Project';
$lang['Post Message'] = 'Post Message';
$lang['To'] = 'To';
$lang['Everyone'] = 'Everyone';
$lang['From'] = 'From';
$lang['Private Messsage'] = 'Private Messsage';
$lang['Note: Only private message to programmer'] = '[ Note: Please enter programmers id for private message with comma separate operator ]';
$lang['Select Project'] = 'Select Project';
$lang['message_validation'] = 'Message';
$lang['You must be logged in as a programmer to post messages on the Project Message Board'] = 'You must be logged in as a programmer to post messages on the Project Message Board';
$lang['Your Message Has Been Posted Successfully'] = 'Your message has been posted successfully';
$lang['You must be logged to post messages on the Project Message Board'] = 'You must be logged to post messages on the Project Message Board';
$lang['You must be post project to invite programmers'] = 'You must be post project to invite programmers';
$lang['You must be logged to invite programmers'] = 'You must be logged to invite programmers';
$lang['There is no open project to Post Mail'] = 'There is no open project to Post Mail';
$lang['You are currently logged in as']='You are currently logged in as';
$lang['Tip']='Tip: You can post programming code by placing it within [code] and [/code] tags.';
$lang['Submit']='Submit';
$lang['Preview']='Preview';
$lang['Hide']='Hide';
$lang['Show']='Show';
$lang['You are currently logged in as']='You are currently logged in as';
A regexp for 'Project' to the right of an equals sign would be:
/=.*Project/
a regexp that also does what you ask for, 'Project' that has no equals sign to its right would be:
/Project[^=]*$/
or a match of your example lines comes to:
/^\$lang['[^']+']\s+=\s+'Project';$/
By placing 'Project' in brackets () you can use that match in a replacement, adding the flag /g finds all occurences in the line.
Edit: Below didn't work because look-behind assertions have to be fixed-length. I am guessing that you want to do this because you want to do a global replace of "Project" with something else. In that case, borrowing rsp's idea of matching a 'Project' that is not followed by an equals sign, this should work:
/Project(?![^=]*\=)/
Here is some example code:
<?php
$str1 = "\$lang['Select Project'] = 'Select Project OK';";
$str2 = "\$lang['Project'] = 'Project';";
$str3 = "\$lang['No Project'] = 'Not Found';";
$str4 = "\$lang['Many Project'] = 'Select Project owner or Project name';";
$regex = '/Project(?![^=]*\=)/';
echo "<pre>\n";
//prints: $lang['Select Project'] = 'Select Assignment OK';
echo preg_replace($regex, 'Assignment', $str1) . "\n";
//prints: $lang['Project'] = 'Assignment';
echo preg_replace($regex, 'Assignment', $str2) . "\n";
//prints: $lang['No Project'] = 'Not Found';
echo preg_replace($regex, 'Assignment', $str3) . "\n";
//prints: $lang['Many Project'] = 'Select Assignment owner or Assignment name';
echo preg_replace($regex, 'Assignment', $str4) . "\n";
This should work:
/(?<=\=.*)Project/
That will match only the word "Project" if it appears after an equals sign. This means you could use it in a substitution too, if you want to replace "Project" on the right-hand-side with something else.
Thx for help. Not sure what is unclear? I just want to find all instances of the word 'Project' but only instances to the right of the equals sign (i.e. not included in square brackets). Hope that helps.
This actually looks like a tricky problem. Consider
[blah blah [yakkity] Project blah] Project [blah blah] [ Project
This is a parsing problem, and I don't know of any way to do it with one regex (but would be glad to learn one!). I'd probably do it procedurally, eliminating the pairs of brackets that did not contain other pairs until there were none left, then matching "Project".
While it's not clear what instances you want to find exactly, this will do:
^.+? = (.+?);
But you might consider using simple string manipulation of your language of choice.
edit
^.+?=.+?(Project).+?;$
will only match lines that have string Project after the equal sign.
[^\[]'[^'\[\]]+'[^\]] seems to accomplish what you want!
This one: [^\[]'[^'\[\]]*Project[^'\[\]]*' will find all strings, not inside of the file that are contained in quotes, and contain the word project.
Another edit: [^\[]'(?<ProjectString>[^'\[\]]*Project[^'\[\]]*)'[^\]]
This one matches the string, and returns it as the group "ProjectString". Any regex library should be able to pull that out sufficiently.