How to remove strings portion in variable and write those values back to variable in one-liner - powershell

i have problem like this, let's say i have an array like this:
$PSnames ='Win10-PS' , 'Server-PS', 'Client-PS'
Now I want to remove the “-PS” portion of each name in the $PSnames variable AND write those values back to the variable but this must be a one-liner. I tried using the foreach-object cmdlet with the pipeline, but the S in Server-PS is also lost.
$PSnames
Win10-PS
Client-PS
Server-PS
$PSnames | ForEach-Object {$_.Trim("-PS")}
Win10
Client
erver
I don't know how to handle and re-insert -PS portion in one-liner.
Could anyone give me an explanation as well as the solution? Thanks and i'm appreciate it!

The .Trim() method does not work as you probably think it does. ;-) I'd recommend using the -replace operator like this:
$PSnames ='Win10-PS' , 'Server-PS', 'Client-PS'
$PSnames = $PSnames -replace '-PS'

Related

Format command output in powershell

I have a output like below from a command
IpPrefix
--------
15.181.232.0/21
142.4.160.136/29
3.2.0.0/24
161.188.154.0/23
Using above output, need write a command in powershell to get format like :
15.181.232.0/21,142.4.160.136/29,3.2.0.0/24,161.188.154.0/23
Basically combine multiple lines to one line with comma separated. Please help.
Welcome to PowerShell! The results of commands are objects. This object you have made has at least 1 property called IpPrefix. If your object is stored in a variable $object, then you can reference the property like this:
$object = (some-command -param something)
$object.IpPrefix
Once you're got the items in just that one column, without the column header, you now have an array of strings. They're still objects, but they are string objects.
The -join operator works against arrays.
$object = (some-command -param something)
$object.IpPrefix -join ','
This will give you what you want in the simplest way possible.
Let's say maybe you don't want to store your data in a variable (aka in Memory). You might have a pipeline or some other situation where storing the data slows you down. You would do that like this:
(some-command -param something).IpPrefix -join ','
Same idea, different syntax. Hope this helps you understand the shell better!

I want to remove certain parts of a certain string in Powershell 7.2.4, how do I do it?

I have the string "url": "https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar". I want to remove everything from the string except https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar (I want to remove the quotes as well).
How do I go about it?
$str = """url"": ""https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar"""
$str.Split(""": """)[1].Replace("""","")
The shortest I could think of
Might have the incorrect indexnumber, just test switching '3'
( $str -split """ )[3]
You could use the -replace operator and extract the section you want.
'"url": "https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar"' -replace '"url": "(.+)"','$1'
However since this appears to be in JSON format you may be better off using ConvertFrom-Json on the entire thing and then accessing the property through dot notation.
It's slightly easier than trying to regex or string match sections of JSON.
$converted = Get-Content file.json | ConvertFrom-Json
$converted.url

Finding the index of a key and value within an array using a wildcard in Powershell

I have been working on an issue and I was able to get done what I need to get done in a relatively decent and acceptable way but I am curious as to why I ran into some of the problems I did.
I'm not too savvy with PowerShell or C# but I have some experience with Java, C++, and a few others. So, if I overlook something really simple, you'll have to forgive me. I'm not looking for a critique of my solution, just some insight into some of the blockades I came across.
What I needed to do was use Powershell to query an LDAP setting. I needed to know MaxConnIdleTime and I needed that either assigned to a variable or accessible through a subroutine [sic] (ex $ldapPolicies.MaxConnIdleTime) so that I could run it through a conditional statement.
Here is how I accomplished it:
$ldap = Get-ADObject -SearchBase "CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=$ENV:COMPUTERNAME,DC=$dc" -Filter 'ObjectClass -like "queryPolicy"' -Properties ldapadminlimits
$ldap = #($ldap.ldapadminlimits)
$ldap | %{
if($_.startswith("MaxConnIdleTime")) {
$match = $_
}
}
I tried NTDSUtil.exe, however, I couldn't redirect the "Show Values" to a text file to read from later and I couldn't write it to a variable in PowerShell.
I tried Start-Transcript and then ran NTDSUtil but it only recorded what occurred within PowerShell and not what happened in NTDSUtil.
Also, I tried giving all of the commands to NTDSUtil at once (NTDSUtil "ldap policies" "connections" "connect to server $ENV:COMPUTERNAME" q "Show Values") but PowerShell doesn't show anything in the console and I have press the exit sequence to return back to PS>.
I know that I could use LDP but I'm not too familiar with ADSI. Research appeared to say that going about attempting to get an LDPdump is a bit antiquated and I pretty much abandoned that attempt.
One of the issues that I had that caused me a small bit of frustration (and the reason I am asking this question) is why can I not search an array and find the index of an item using a wildcard? I tried doing this:
$ldap.IndexOf("MaxConnIdleTime*")
AND
$ldap.IndexOf($ldap -like "MaxConnIdleTime*")
but it always returned -1.
It would work correctly if I tried:
$ldap.IndexOf("MaxConnIdleTime=100")
given that the value was indeed 100. But I am validating that the value was correct.
I know that I could just do something like this:
if($ldap -contains "MaxConnIdleTime=100") {
DO SOMETHING...
} else {
DO SOMETHING ELSE...
}
Why is it that I can't search an array using a wildcard operator? There was no ambiguity, so, it should have worked, right?
I'm not looking for a critique of how I accomplished this, I'm just wanting to understand why it behaved like it did.
Thanks.
I don't think there's a straightforward "search an array by wildcard and return an index" cmdlet, method, statement, etc. in PowerShell.
.IndexOf is not designed to work with a wildcard.
When you used the -like operator on the array, you likely found only a single matching object, but -like returns an array of matches when used on an array.
Passing the array into .IndexOf() then looks for an array element that is itself an array, even if that array only has one object.
This would work:
$ldap.IndexOf(($ldap -like "MaxConnIdleTime*")[0])
As long as you always wanted to find the first one.

Pipes in replace causing line to be duplicated

I have a script that I need to replace a couple of lines in. The first replace is going fine but the second is wiping out my file and duplicating the line multiple times.
My code
(get-content $($sr)) -replace 'remoteapplicationname:s:SHAREDAPP',"remoteapplicationcmdline:s:$($sa)" | Out-File $($sr)
(get-content $($sr)) -replace 'remoteapplicationprogram:s:||SHAREDAPP',"remoteapplicationprogram:s:||$($sa)" | Out-File $($sr)
The first replace works perfectly. The second one is causing this:
remoteapplicationprogram:s:||stagaredrremoteapplicationprogram:s:||stagarederemoteapplicationprogram:s:||stagareddremoteapplicationprogram:s:||stagarediremoteapplicationprogram:s:||stagaredrremoteapplicationprogram:s:||stagarederemoteapplicationprogram:s:||stagaredcremoteapplicationprogram:s:||stagaredtremoteapplicationprogram:s:||stagaredcremoteapplicationprogram:s:||stagaredlremoteapplicationprogram:s:||stagarediremoteapplicationprogram:s:||stagaredpremoteapplicationprogram:s:||stagaredbremoteapplicationprogram:s:||stagaredoremoteapplicationprogram:s:||stagaredaremoteapplicationprogram:s:||stagaredrremoteapplicationprogram:s:||stagareddremoteapplicationprogram:s:||stagared:remoteapplicationprogram:s:||stagarediremoteapplicationprogram:s:||stagared:remoteapplicationprogram:s:||stagared1remoteapplicationprogram:s:||stagared
etc...
Is this because of the ||? If so, how do I get around it?
Thanks!
To begin with, you should be using slightly more meaningful names for your variables. Especially if you want someone else to be reviewing your code.
The gist of your issue is that -replace supports regexes (regular expressions), and you have regex control characters in your pattern string. Consider the following simple example, and notice everywhere the replacement string is found:
PS C:\Users\Matt> "ABCD" -replace "||", "bagel"
bagelAbagelBbagelCbagelDbagel
-replace is also an array operator, so it works on every line of the input file, which is nice. For simplicity's sake, if you are not using a regex, you should just consider using the string method .Replace(), but it is case-sensitive, so that might not be ideal. So let's escape those control characters in the easiest way possible:
$patternOne = [regex]::Escape('remoteapplicationname:s:SHAREDAPP')
$patternTwo = [regex]::Escape('remoteapplicationprogram:s:||SHAREDAPP')
(get-content $sr) -replace $patternOne, "remoteapplicationcmdline:s:$sa" | Out-File $($sr)
(get-content $sr) -replace $patternTwo, "remoteapplicationprogram:s:||$sa" | Out-File $($sr)
Now we get both patterns matched as you have them written. Run $patternTwo on the console to see what has changed to it! $patternOne, as written, has no regex control characters in it, but it does not hurt to use the escape method if you are just expecting simple matching.
Aside from the main issue pointed out, there is also some redundancy and misconception that can be addressed here. I presume you are updating a source file to replace all occurrences of those strings, yes? Well, you don't need to read the file in twice, given that you can chain -replace:
$patternOne = [regex]::Escape('remoteapplicationname:s:SHAREDAPP')
$patternTwo = [regex]::Escape('remoteapplicationprogram:s:||SHAREDAPP')
(get-content $sr) -replace $patternOne, "remoteapplicationcmdline:s:$sa" -replace $patternTwo, "remoteapplicationprogram:s:||$sa" |
Set-Content $sr
Perhaps that will do what you intended.
You might notice that I've removed the subexpressions operators ($(...)) around your variables. While they have their place, they don't need to be used here. They are only needed inside more complicated strings, like when you need to expand object properties or something.

Issue with trying to pass variable into [adsisearcher]

I apologize in advance if this is something simple, but I've been researching for a few days now and unable to resolve on my own or find another route to explore.
Essentially I have the below which works and returns exactly what I need:
([adsisearcher]'(&(objectClass=user (samaccountname='*dland*'))').FindOne().Properties['samaccountname']
which returns the username containing dland in it. I want to replace the dland with a variable ($usrNme1), but it errors out with "Unexpected token '$usrNme1'))'' in expression or statement."
I was able to get it working locally with using the ActiveDirectory module using the following:
Get-ADUser -Filter {SAMAccountName -like $usrNme1} | select-object -Property SAMAccountName
But unfortunately I cannot use that against other computers in this environment and have to find another way and this is as far as I've gotten to finding a replacement.
Any assistance here would be greatly appreciated :) This is the last piece of the puzzle for me and its frustrating being so close and not being able to figure it out! Thanks in advance for taking the time :)
Edit: Forgot to comment, this script is going to be pushed out and run locally on windows 7 machines, which is part of the reason why I can't use Get-ADUser.
Thanks,
David
Your query is a little malformed as it is missing a bracket after user but you can put variables in the string easily like in the following example. Variables placed inside double quotes will expand just fine* (Most of the time. Object parameters require subexpressions).
$accountname = "mcame*"
$query = "(&(objectClass=user)(samaccountname=$accountname))"
([adsisearcher]$query).FindOne().Properties['samaccountname']
Note: if you look at this question you will see issues doing the wildcard search that your are. If you have a large organization you might need to reconsider using leading and trailing asterices or whatever the plural is.
You original query
Aside from the bracket the reason it was not working was since you were using the single quotes. If you look at this resource it goes on to say
Comparative strings do NOT appear in quotation marks. A filter for the
displayName 'Philipp Foeckeler' would read as follows:
(displayName=Philipp Foeckeler).
Query should have worked without those inner quotes.
Try this:
$foo = '*jsm*'
([adsisearcher]"(&(objectClass=user) (samaccountname=$foo))")