I'm trying to sort servers by the 2nd index of the name.
The server names are taken from file paths where they are the BaseName of the file.
I know that Select-Object has the parameter -Index, but I don't think that will work.
I am assuming that the best approach is with a PowerShell RegEx like "(?:^a-z))". This returns an unsorted list and I'm still googling around for a pattern that will sort by the 2nd Index.
Example of the Intended Output
Group the servers by name CC or DD
Server
------
ABCCWS01
CDCCWS01
ABDDWS01
CDDDWS01
Current Output
Sorts alphabetically by -Property name
$servers = Get-Item -Path
C:\ABDDWS01.ServerData,
C:\ABCCWS01.ServerData,
C:\CDCCWS01.ServerData,
C:\CDDDWS01.ServerData | Group BaseName -AsHashtable
foreach($computer in $servers.GetEnumerator() | Sort-Object -Property name)
{ ...DoSomething... }
Server
------
ABCCWS01
ABDDWS01
CDCCWS01
CDDDWS01
Then I tried to implement a PowerShell RegEx. But I'm stuck on how to properly use this to sort by the 2nd index. This example has no affect and returns the list unsorted. I've tried subbing in different patterns at the end "(?:^a-z))". So far my attempts either return the list unsorted or just a segment of the list.
I've googled around and tried many different things. If someone else wants to help puzzle this out, it is much appreciated.
Sort-Object -Property #{Expression={[RegEx]::Match($_.basename, "(?:^a-z))")}}
Sort-Object works by "ranking" each input according to the resulting value of calculating one or more property expressions against each input item - in your existing example, based on the the value of the name property.
As you've already found, property expressions doesn't have to be the value of any existing property though - they can be made up of anything - just pass a script block in place of the property name:
... |Sort-Object -Property {$_.name[1]}
The reason it doesn't work in your example is that the expression [RegEx]::Match($_.basename, "(?:^a-z))") returns a [System.Text.RegularExpressions.Match] object - and those can't be meaningfully compared to one another.
If you change the expression to resolve to a string instead (the matched value for example), it'll work:
... |Sort-Object -Property #{Expression={[RegEx]::Match($_.basename, "(?:^a-z))").Value}}
# or
... |Sort-Object -Property {[RegEx]::Match($_.basename, "(?:^a-z))").Value}
Related
I’m trying to obtain the count of all title containing a specific string from a dictionary in a jinja template.
I have tried many variant with select and other test and haven’t found the right way to do so.
This is not for ansible for which I have found many solutions to fix this issue.
Also the test equalto does not work since I do not have an exact match on the string and doesn’t seem to take regex.
{{ Dictionnary | selectattr("title", "in","MyString") | list | count }}
It seems that the string never gets properly evaluated because it always returns 0.
The selectattr without test return the right number of total titles.
I wonder if we could evaluate it with an if statement somehow.
I'm trying to convert the output of a powershell (AWS Tools) command to strings so that I can export them to CSV or HTML. I for the life of me can't figure it out. I've seen comments on hashtables, naming elements, etc. Nothing seems to help me. (I'm very much a newbie).
This is what I got.
This command
(Get-IAMAccountAuthorizationDetail).UserDetailList | Select UserName, Grouplist
Will output this (with better spacing):
UserName GroupList
-------- ---------
User1 {Admins,Test}
User2 {Admins}
I cant' seem to figure out how to get this data so that it can be converted to CSV or HTML. Those brackets are an indication its an object, array or something. Can someone show me the code that would convert this to text or something that the Convertto-CVS o Convertto-HTML commands would work.
The output (subset) of the Get-Member Command is this:
TypeName : Amazon.IdentityManagement.Model.UserDetail
Name : Equals
MemberType : Method
Definition : bool Equals(System.Object obj)
TypeName : Amazon.IdentityManagement.Model.UserDetail
Name : GetHashCode
MemberType : Method
Definition : int GetHashCode()
TypeName : Amazon.IdentityManagement.Model.UserDetail
Name : GroupList
MemberType : Property
Definition : System.Collections.Generic.List[string] GroupList {get;set;}
Thanks
You could do something like the following, which will create a semi-colon delimited list within the GroupList cell:
(Get-IAMAccountAuthorizationDetail).UserDetailList |
Select-Object UserName,#{n='GroupList';e={$_.Grouplist -join ';'}}
Explanation:
The syntax #{n='Name';e={Expression}} is called a calculated property as explained at Select-Object. Here is some information about the calculated property:
It is a hash table with custom properties.
The first property is Name, which is a label for your expression output. n,Name,l, and label are all acceptable property names for that property.
The value passed to n is just a string that you are creating. It is the property name that will show up in your output, and it does not need to already exist in your object. Your actual property is called GroupList. As an example with n='All The Groups', the property name would becomeAll The Groups` in your output. There is nothing wrong with reusing the same name the property currently has.
The Expression or e is the ScriptBlock, which is why it is surrounded by {}. The ScriptBlock is responsible for producing the value in your custom property.
$_ is the current pipeline object passed into the ScriptBlock. This means if you have a collection (just like you do in your case), $_ will represent each of those items in order.
If you want to add another calculated property, just add a comma after the last and use the calculated property syntax like so:
Select-Object #{n='CustomProperty1';e={$_.ObjectProperty1}},#{n='CustomProperty2';e={$_.ObjectProperty2}}
Is there any simple way of getting a list of all the OUs located one level under a given OU?
i.e. I have an OU called "Clients" and one level under this OU there are multiple OUs , one for each client. i.e. CAS, ADI, PMA
I would like to get a list with the description of these sub OUs.
Following the previous example, the result would be: "Casio, Adidas, Puma"
I tried Get-ADOrganizationalUnit but I couldn't figure out a way of doing this.
Thanks
Would this help you out:
$OU = 'OU=Europe,OU=World,DC=domain,DC=net'
Get-ADOrganizationalUnit -SearchBase $OU -SearchScope Subtree -Filter * |
Select-Object DistinguishedName, Name
You can find information on how to use the CmdLet Get-ADOrganizationalUnit by typing:
help Get-ADOrganizationalUnit -Example
I have a variable $yearMonth := "2015-02"
I have to search this date on an element Date as xs:dateTime.
I want to use regex expression to find all files/documents having this date "2015-02-??"
I have path-range-index enabled on ModifiedInfo/Date
I am using following code but getting Invalid cast error
let $result := cts:value-match(cts:path-reference("ModifiedInfo/Date"), xs:dateTime("2015-02-??T??:??:??.????"))
I have also used following code and getting same error
let $result := cts:value-match(cts:path-reference("ModifiedInfo/Date"), xs:dateTime(xs:date("2015-02-??"),xs:time("??:??:??.????")))
Kindly help :)
It seems you are trying to use wild card search on Path Range index which has data type xs:dateTime().
But, currently MarkLogic don't support this functionality. There are multiple ways to handle this scenario:
You may create Field index.
You may change it to string index which supports wildcard search.
You may run this workaround to support your existing system:
for $x in cts:values(cts:path-reference("ModifiedInfo/Date"))
return if(starts-with(xs:string($x), '2015-02')) then $x else ()
This query will fetch out values from lexicon and then you may filter your desired date.
You can solve this by combining a couple cts:element-range-querys inside of an and-query:
let $target := "2015-02"
let $low := xs:date($target || "-01")
let $high := $low + xs:yearMonthDuration("P1M")
return
cts:search(
fn:doc(),
cts:and-query((
cts:element-range-query("country", ">=", $low),
cts:element-range-query("country", "<", $high)
))
)
From the cts:element-range-query documentation:
If you want to constrain on a range of values, you can combine multiple cts:element-range-query constructors together with cts:and-query or any of the other composable cts:query constructors, as in the last part of the example below.
You could also consider doing a cts:values with a cts:query param that searches for values between for instance 2015-02-01 and 2015-03-01. Mind though, if multiple dates occur within one document, you will need to post filter manually after all (like in option 3 of Navin), but it could potentially speed up post-filtering a lot..
HTH!
I am attempting to write a script that collects user input using getopts. I need to be able to limit restrict the values the user can enter. I see how to set a default value but, I have been unable to find any way to set a list of allowed values... so,
I am attempting to use Config::Simple to create an array from values stored in a text file to use to validate against.
contents of values.txt
ChangeCategories resolution, storm
contents of main.pl
#---create array from values.txt ChangeCategories
my #chg_cats = $cfg->param("ChangeCategories");
unlink $_ for #chg_cats;
#----grab user input via getopts
my $change_categories = $opt_c || die "Please enter a valid change category; #chg_cats";
The issue occurs when I attempt to do the pattern match, it is matching only the first value listed on the ChangeCategories line in the values.txt file.
#---pattern mathching code
my $valid_category;
chomp(#chg_cats);
foreach (#chg_cats) {
##foreach my $line (#chg_cats) {
if(($_ =~ $change_categories) )
#if(($_ =~ m/$change_categories/) )
#if(($_ eq $change_categories) )
As you can see, I have tried numerous constructs to correct this and verify that I get correct matching results every time. I am not sure if this is somehow related to 'chomping' but, I have tried every pattern I can think of. I am a beginner to Perl and would very much appreciate any and all help.... and if anyone can tell me an easier/cleaner way to achieve this result, I would be very grateful