PowerShell - xml files with conflicting multiple namespaces on the same element name - powershell

Related to PowerShell 5.1
I was playing around with XML to show how to handle conflicting namespaces. Here's the example I created:
<Employees>
<ms:Employee id='1' xmlns:ms="MicrosoftEmployees">
<FirstName>Bill</FirstName>
<LastName>Gates</LastName>
</ms:Employee>
<ms:Employee id='2' xmlns:ms="MicrosoftEmployees">
<FirstName>Paul</FirstName>
<LastName>Allen</LastName>
</ms:Employee>
<ap:Employee id='1' xmlns:ap="AppleEmployees">
<Name>Steve Jobs</Name>
</ap:Employee>
<ap:Employee id='2' xmlns:ap="AppleEmployees">
<Name>Steve Wozniak </Name>
</ap:Employee>
</Employees>
The scenario might be combining data from two different companies.
PowerShell demonstration program:
cls
$filename = "c:\XMLClass\IntroSamples\Sample05_Simpler_Namespace.xml"
[xml]$xmlDoc = Get-Content $filename
$xmlDoc.Employees.Employee[0]
$xmlDoc.Employees.Employee[1]
$xmlDoc.Employees.Employee[2]
$xmlDoc.Employees.Employee[3]
Output:
id ms FirstName LastName
-- -- --------- --------
1 MicrosoftEmployees Bill Gates
2 MicrosoftEmployees Paul Allen
1
2
Is there anyway to get a more logical output?
It seems like PowerShell locks into the first schema it sees for the Employee element, then cannot show the Name element of the Apple employees. This actually makes sense, but I was just checking to see if there is something fancier to handle this that I might be missing.
I know I could use SelectSingleNodes and XPath, but was just trying to see if and how PowerShell could handle this "out of the box".
If I reverse the code:
$xmlDoc.Employees.Employee[2]
$xmlDoc.Employees.Employee[3]
$xmlDoc.Employees.Employee[1]
$xmlDoc.Employees.Employee[0]
Then the output is:
id ap Name
-- -- ----
1 AppleEmployees Steve Jobs
2 AppleEmployees Steve Wozniak
1 ms:Employee
2 ms:Employee

Use format list to see all the properties. Format-table doesn't handle different sets of properties well.
$xmldoc.employees.employee | format-list
id : 1
ms : MicrosoftEmployees
FirstName : Bill
LastName : Gates
id : 2
ms : MicrosoftEmployees
FirstName : Paul
LastName : Allen
id : 1
ap : AppleEmployees
Name : Steve Jobs
id : 2
ap : AppleEmployees
Name : Steve Wozniak

Related

Duplicate values but with different strings

Hello if i have 2 text files like this
file1
jack : 10
donald : 50
mark : 20
florence : 15
ariel : 50
arnold : 50
file2
jack
country : ohaio
donald
country : italy
mark
country : france
florence
country : china
ariel
country :america
arnold
country: japan
how can i to get country names of people older than 20 looping through ages in file1 to get names of people first then after i get names loop through them in file2 to get countries.// don't know how to deal with duplicate ages,this is just sample files there is a lot more values than that.
so output should be something like this:
ages
10
20
50
15
50
50
values over 20
50
50
50
names
donald
ariel
arnold
countries
italy
america
japan
the following code presumes the entries in the two files are in the EXACT same sequence ... and they have EXACTLY the same number of entries. [grin]
what it does ...
sets the name & location of the input files
creates the files to work with
comment out or remove this region when ready to work with real data.
reads in the 1st file as an array of single lines
reads in the 2nd file as an array of 3-line chunks
iterates thru the two collections in parallel using the index number of the 1st collection
the .GetUpperBound(0) gets the upper limit of the zero axis of the collection.
builds a PSCustomObject of the desired items
it uses the $Index to decide what to work on.
the [1] after the Country file index grabs the 2nd line of the 3-line chunk.
sends the PSCO out to the $Results collection
displays it on screen
filters the collection for the items where the .Age property is over 20
the code ...
$File_1_Name = "$env:TEMP\3N16M4_File1.txt"
$File_2_Name = "$env:TEMP\3N16M4_File2.txt"
#region >>> create files to work with
$NameAge = #'
jack : 10
donald : 50
mark : 20
florence : 15
ariel : 50
arnold : 50
'# | Set-Content -LiteralPath $File_1_Name -ErrorAction 'SilentlyContinue'
$NameCountry = #'
jack
country : ohaio
donald
country : italy
mark
country : france
florence
country : china
ariel
country :america
arnold
country: japan
'# | Set-Content -LiteralPath $File_2_Name -ErrorAction 'SilentlyContinue'
#endregion >>> create files to work with
$NameAge = Get-Content -LiteralPath $File_1_Name
# the "-ReadCount" parameter grabs lines in groups
$NameCountry = Get-Content -LiteralPath $File_2_Name -ReadCount 3
# this code presumes the two files are in the EXACT same sequence
# and that they have EXACTLY the same number of entries
$Results = foreach ($Index in 0..$NameAge.GetUpperBound(0))
{
[PSCustomObject]#{
Name = $NameAge[$Index].Split(':')[0].Trim()
Age = $NameAge[$Index].Split(':')[-1].Trim()
Country = ($NameCountry[$Index][1] -replace '(?ms).+:', '').Trim()
}
}
# show whole collection on screen
$Results
'=' * 30
# show the filtered results
$Results.Where({$_.Age -gt 20})
on screen display - the whole collection is above the line, the filtered items are below it ...
Name Age Country
---- --- -------
jack 10 ohaio
donald 50 italy
mark 20 france
florence 15 china
ariel 50 america
arnold 50 japan
==============================
donald 50 italy
ariel 50 america
arnold 50 japan

Regular expression multiple cut on string selenium ide

My basic string structure :
Gestion des tickets - Compte 5 - SARL PROJET DE BLI[Commercial: SNOW Jon]
Explanation of decompose string :
- "5" : an ID
- "SARL PROJET DE BLI" : a company name
- "SNOW Jon" : the full name of a sale agent, composed by "last name" + "first name"
What I've done and works :
store my structured string : storeText | css=h1 | h13
store the ID : storeEval | storedVars['h13'].split(' ')[5] | final_id
What I really needs : 2 regular expressions for store the 2 last one, company name and full name of sale agent. I need only what is between "" whithout useless space on begin and end.
I already try something like this :
storeEval | storedVars['h13'].match(/- \/((?:.|<br />)*?) [/) | final_company
But don't works ... perhaps the space ...
For company name i want store ALL BETWEEN "- " AND " ["
same for the full name : store ALL BETWEEN ": " AND "]"
Did someone have a solution ? I'm not very good with regular expression... in english too :p
I finally find it myself, i try this and it works:
storeEval | storedVars['h13'].match(/- ([a-zA-Z ]+) [/)[1] | fi_rs
storeEval | storedVars['h13'].match(/\: ([^\]]+)\]/)[1] | fi_rs2
Bye.

Select-Object on imported CSV column with space in name returned empty values

I'm writing a script to process a CSV file created on a non-Windows platform.
The CSV has a lot of columns, not all of which I want.
They are:
TypeName: System.Management.Automation.PSCustomObject
Name
----
Equals
GetHashCode
GetType
ToString
AVGCPUTIME
AVG_CARDS_PN
AVG_CARDS_RD
AVG_ELAPSED
AVG_IO_TIME
AVG_LINES_PRNTD
AVG_OV_MEM
AVG_OV_MEM_INT
AVG_SAV_MEM
AVG_SAV_MEM_INT
BEGINDATE
BEGINTIME
CARDS_PN
CARDS_RD
CPUTIME
DCKEYIN
ELAPSED
ENDDATE
ENDTIME
IO_TIME
JOBNAME
JOBSTATUS
JOBTYPE
LINES_PRNTD
MANUAL
MIXNUM
OV_MEM
OV_MEM_INT
PCJOB
REFNUM
RUNTIME PARAMETERS ...
SAV_MEM
SAV_MEM_INT
SCHEDDATE
SCHEDTIME
SYSTEM
TASKNUM
USERCODE
I have a problem selecting the property, RUNTIME PARAMETERS - both of the following bits of code result in me having a column with the name I expect, but every value in that column is empty (I'm using Out-GridView just now while writing the script, the final script will output data to a new file once I've filtered with Where-Object etc to pull out only the info I need - the intention is for the PowerShell script to run as an automated process when the file lands on the server).
$Inp = Import-Csv K:\LOGSTATS_ALLBATCH_20150602165021.CSV
$Inp| Select USERCODE,JOBNAME,MIXNUM,TASKNUM,BEGINDATE,BEGINTIME,ENDDATE,ENDTIME,DCKEYIN,MANUAL,JOBSTATUS,JOBTYPE,CPUTIME,IOTIME,ELAPSED,SYSTEM,"RUNTIME PARAMETERS"|OGV
$Inp = Import-Csv K:\LOGSTATS_ALLBATCH_20150602165021.CSV
$Inp| Select USERCODE,JOBNAME,MIXNUM,TASKNUM,BEGINDATE,BEGINTIME,ENDDATE,ENDTIME,DCKEYIN,MANUAL,JOBSTATUS,JOBTYPE,CPUTIME,IOTIME,ELAPSED,SYSTEM,#{Name="PARAMS";Expression={$_."RUNTIME PARAMETERS"}}|OGV
Here's a sample of the input:
"REFNUM","USERCODE","JOBNAME","MIXNUM","TASKNUM","BEGINDATE","BEGINTIME","ENDDATE","ENDTIME","SCHEDDATE","SCHEDTIME","DCKEYIN","MANUAL","PCJOB","JOBSTATUS","JOBTYPE","CPUTIME","AVGCPUTIME","IO_TIME","AVG_IO_TIME","ELAPSED","AVG_ELAPSED","SAV_MEM","AVG_SAV_MEM","OV_MEM","AVG_OV_MEM","SAV_MEM_INT","AVG_SAV_MEM_INT","OV_MEM_INT","AVG_OV_MEM_INT","LINES_PRNTD","AVG_LINES_PRNTD","CARDS_RD","AVG_CARDS_RD","CARDS_PN","AVG_CARDS_PN","SYSTEM","RUNTIME PARAMETERS"
01141730,TEST ,CONTROLCARD ,09376,00000,20150601,0106,20150601,0106,20150601,0100,N,N,N,COMPLETEDOK ,SCHEDULED ,0000000000,0000000000,0000000000,0000000000, 0:00:00, 0:00:00,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,01234,"BETA" "INCR" "ALL"
And here's an example of the output from the 2nd piece of code, piped through Format-List:
USERCODE : TEST
JOBNAME : CONTROLCARD
MIXNUM : 09376
TASKNUM : 00000
BEGINDATE : 20150601
BEGINTIME : 0106
ENDDATE : 20150601
ENDTIME : 0106
DCKEYIN : N
MANUAL : N
JOBSTATUS : COMPLETEDOK
JOBTYPE : SCHEDULED
CPUTIME : 0000000000
IOTIME :
ELAPSED : 0:00:00
SYSTEM : 01234
PARAMS :
Any help understanding why I'm either not selecting the property with the space in it, or not seeing the values, would be greatly appreciated!
EDIT:
It seems the code was ok but there is a possible issue with the encoding of the header - adding screenshot from hex editor for #Ansgar Wiechers
It seems your input file contains null characters that mess up your field names. You can remove them like this:
$file = 'C:\path\to\your.csv'
(Get-Content $file -Raw) -replace [string][char]0 | Set-Content $file
Removing all null characters should be safe, since your file appears to be ASCII encoded (no BOM in your screenshot).
The removal operation took about a second when I tested it on a 13 MB sample file.
Warning: Do NOT use this on Unicode encoded files (UTF-8, UTF-16, ...) or you'll end up with gibberish in your files.

How can I access properties of the IpPermissions property of Get-EC2SecurityGroup?

I am trying to get a list of security groups. (Successful - Using Get-EC2SecurityGroup)
Get a list of the specific IPPermissions associated with each security group. ( Successful - Using (Get-EC2SecurityGroup).IpPermissions )
Only return results where the FromPort = "xxx" ( Unsuccessful - Not sure how to access the FromPort property that is returned in the result list )
Ultimately what I am trying to accomplish is:
Get a list of existing security groups, and loop through each group.
While looping through each group, call the IpPermissions, and look for the specific FromPort "xxx".
If the FromPort is a match, record the other properties: (FromPort, IpProtocol, IpRanges, ToPort, UserIdGroupPairs)
Problem I am having
I am not sure how to do a loop using the amazon objects
I cant seem to access the properties even though they appear to be named and have values.
I have tried using -Filter with many different iterations, with no success.
The documentation seems self-referencing, and the examples I have run across dont get down to this level of detail.
Results returned from (Get-EC2SecurityGroup).IpPermissions
FromPort : 123
IpProtocol : tcp
IpRanges : {0.0.0.0/0}
ToPort : 123
UserIdGroupPairs : {}
Here's an example that does as you've described:
Filters security group objects by FromPort
Of the matched security groups, output IpProtocol, IpRanges, ToPort, and UserIdGroupPairs.
Code:
# Example using port 22
PS C:\> $port = 22
PS C:\> Get-EC2SecurityGroup |
? { $_.IpPermissions.FromPort -eq $port } |
% { $_.IpPermissions } |
Select -property IpProtocol, IpRanges, ToPort, UserIdGroupPairs
Output:
IpProtocol IpRanges ToPort UserIdGroupPairs
---------- -------- ------ ----------------
tcp {0.0.0.0/0} 22 {}
... ... ... ...

How to split multiple datas from multiple lines in perl

Firstly, I have the data below:
*********************************************************************
TEST CASE
*********************************************************************
test results for the last 1 run(s)
TEST TITLE GROUP PRIO R-STAT R-TIME VERDICT VERDICT-TEXT
------------------------- ---------------------------------------- -------- ---- ------ ------------ -------- --------------------------------------------------
TESTCASE1 TC1 ABC 1 PASS 00:00:09.572 PASS nothing
TESTCASE2 TC2 DEF 2 PASS 00:00:01.650 PASS nothing
----------------------------------------------------------------------------------------------------
NUMBER OF : 2
NUMBER OF TC: 2
*********************************************************************
VERDICT: PASS
*********************************************************************
I would like to perform lines:
TESTCASE1 TC1 ABC 1 PASS 00:00:09.572 PASS nothing
TESTCASE2 TC2 DEF 2 PASS 00:00:01.650 PASS nothing
and split first lines and last lines.
How can I do that?
ADDITIONAL:
Sorry for too late reply, i want to split
*********************************************************************
TEST CASE
*********************************************************************
test results for the last 1 run(s)
TEST TITLE GROUP PRIO R-STAT R-TIME VERDICT VERDICT-TEXT
------------------------- ---------------------------------------- -------- ---- ------ ------------ -------- --------------------------------------------------
just handled two lines
TESTCASE1 TC1 ABC 1 PASS 00:00:09.572 PASS nothing
TESTCASE2 TC2 DEF 2 PASS 00:00:01.650 PASS nothing
i use while loop to check line by line, the problem is it will be looped all of lines whereas i want two lines only.
You can try this to get first and last line from file:
cat filename | grep "^TESTCASE" | sed -n '1p;$p'