Assistance Splitting Column Data into Multiple Columns from Import-CSV - powershell

I import a CSV using import-csv command:
$P = Import-Csv "C:\MyCSV.csv"
I then run 'Get-Member':
$P | Get-Member
Output:
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Message NoteProperty string Message=ABC 1234 DEFGH 123:3212 IJKLM NOPQRST 23\13\19 ABC1234 0978AJD
I then run 'Format-Table':
$P | Format-Table
Output:
Message
-------
ABC 1234 DEFGH 123:3222 IJKNM NOPQRHT 23\13\19 ABC1234 0978AJD...
BAC 3214 DEFAH 123:3422 IJFLM NOPQRAT 23\13\18 ABC1234 0978AJD...
CEC 1534 DEFIH 123:3312 IJALM NOPQRFT 23\13\17 ABC1234 0978AJD...
3BC 1144 DAFGH 123:3612 IJZLM NOPQRGT 23\13\16 ABC1234 0978AJD...
I want to split this output up further by delimiting by space. I do not care about properly naming each new column. I just want to be able to then select whatever column header certain text falls under and export that output to a new CSV.
Ideal output:
Column1 Column2 Column3 Column4 etc
------- ------- ------- -------
ABC 1234 DEFGH 123:3222 etc
So I can then run a command such as:
select Column5,Column8
or a command like
select Column15,Column58
Can anyone assist me with this?

This ought to do the job:
# fake reading in a CSV file as text
# in real life, use Get-Content
$InStuff = #'
Message
ABC 1234 DEFGH 123:3222 IJKNM NOPQRHT 23\13\19 ABC1234 0978AJD
BAC 3214 DEFAH 123:3422 IJFLM NOPQRAT 23\13\18 ABC1234 0978AJD
CEC 1534 DEFIH 123:3312 IJALM NOPQRFT 23\13\17 ABC1234 0978AJD
3BC 1144 DAFGH 123:3612 IJZLM NOPQRGT 23\13\16 ABC1234 0978AJD
'# -split [environment]::NewLine
$ColCount = $InStuff[1].Split(' ').Count
$Collection = $InStuff |
Select-Object -Skip 1 |
ConvertFrom-Csv -Delimiter ' ' -Header (1..$ColCount).ForEach({"Column_$_"})
$Collection |
Select-Object -Property 'Column_3', 'Column_7'
Output:
Column_3 Column_7
-------- --------
DEFGH 23\13\19
DEFAH 23\13\18
DEFIH 23\13\17
DAFGH 23\13\16
What it does:
reads the file in as a text file, not a CSV file
gets a count on the # of columns
skips the 1st line
creates a CSV import
sets the delimiter to <space>
sets the header to the range of 1..$ColCount
filters for the desired columns

Lee, I am currently unable to edit my own post because my reputation is too low -_-. As such, I will respond to the post with the information you're requesting:
For your further insight, here is my current code that's not working:
$InStuff = Get-Content -Path 'MyCSV.csv'
$ColCount = $InStuff[1].Split(' ').Count
$Collection = $InStuff |
Select-Object -Skip 1 |
ConvertFrom-Csv -Delimiter ' ' -Header (1..$ColCount).ForEach({"Column_$_"})
$Collection
Output. As you can see, all columns except Column_1 are empty:
Column_1 : <134>Dec 13 13:50:23 10.137.119.42 MSWinEventLog 1 Security 123456789
Thu Dec 13 13:50:23 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy625 N/A
Success Audit mydc1.dy625.com Directory Service Access An operation was performed on
an object. Subject : Security ID: S-123456 Account Name: dy625 Account
Domain: MyCompany Logon ID: XXXXXXXX Object: Object Server: DS Object
Type: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Object Name: %{XXXXXXXX-XXXXXXXX-XXXXXXXX}
Handle ID: 0x0 Operation: Operation Type: Object Access Accesses: Write
Property Access Mask: 0x20 Properties: Write Property {XXXX-XXXX-XXXXX} {XXXX-
XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} Additional Information:
Parameter 1: - Parameter 2: 123456
Column_2 :
Column_3 :
Column_4 :
Column_5 :
...
Column_1 : <134>Dec 13 13:50:18 10.137.119.42 MSWinEventLog 1 Security 123456789
Thu Dec 13 13:50:18 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy626 N/A
Success Audit mydc1.dy625.com Directory Service Access An operation was performed on
an object. Subject : Security ID: S-123456 Account Name: dy626 Account
Domain: MyCompany Logon ID: XXXXXXXX Object: Object Server: DS Object
Type: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Object Name: %{XXXXXXXX-XXXXXXXX-XXXXXXXX}
Handle ID: 0x0 Operation: Operation Type: Object Access Accesses: Write
Property Access Mask: 0x20 Properties: Write Property {XXXX-XXXX-XXXXX} {XXXX-
XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} Additional Information:
Parameter 1: - Parameter 2: 123456
Column_2 :
Column_3 :
Column_4 :
Column_5 :
...
Column_1 : <134>Dec 13 13:50:14 10.137.118.22 MSWinEventLog 1 Security 123456789
Thu Dec 13 13:50:14 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy627 N/A
Success Audit mydc1.dy625.com Directory Service Access An operation was performed on
an object. Subject : Security ID: S-123456 Account Name: dy627 Account
Domain: MyCompany Logon ID: XXXXXXXX Object: Object Server: DS Object
Type: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Object Name: %{XXXXXXXX-XXXXXXXX-XXXXXXXX}
Handle ID: 0x0 Operation: Operation Type: Object Access Accesses: Write
Property Access Mask: 0x20 Properties: Write Property {XXXX-XXXX-XXXXX} {XXXX-
XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} Additional Information:
Parameter 1: - Parameter 2: 123456
Column_2 :
Column_3 :
Column_4 :
Column_5 :
As I stated before, I think the issue is that I don't know how to re-implement the '-split [environment]::NewLine' command with the updated syntax. As you can, see it's missing. I think this is the cause of the issue.
When I input the raw text as you suggest, with the entire first 3 lines, your syntax works correctly, as expected.
$InStuff = #'
Message
<134>Dec 13 13:50:23 10.137.119.42 MSWinEventLog 1 Security 123456789 Thu Dec 13 13:50:23 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy625 N/A Success Audit mydc1.dy625.com Directory Service Access An operation was performed on an object. Subject : Security ID: S-123456 Account Name: dy625 Account Domain: MyCompany Logon ID: XXXXXXXX Object: Object Server: DS Object Type: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Object Name: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Handle ID: 0x0 Operation: Operation Type: Object Access Accesses: Write Property Access Mask: 0x20 Properties: Write Property {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} Additional Information: Parameter 1: - Parameter 2: 123456
<134>Dec 13 13:50:18 10.137.119.42 MSWinEventLog 1 Security 123456789 Thu Dec 13 13:50:18 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy626 N/A Success Audit mydc1.dy625.com Directory Service Access An operation was performed on an object. Subject : Security ID: S-123456 Account Name: dy626 Account Domain: MyCompany Logon ID: XXXXXXXX Object: Object Server: DS Object Type: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Object Name: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Handle ID: 0x0 Operation: Operation Type: Object Access Accesses: Write Property Access Mask: 0x20 Properties: Write Property {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} Additional Information: Parameter 1: - Parameter 2: 123456
<134>Dec 13 13:50:14 10.137.118.22 MSWinEventLog 1 Security 123456789 Thu Dec 13 13:50:14 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy627 N/A Success Audit mydc1.dy625.com Directory Service Access An operation was performed on an object. Subject : Security ID: S-123456 Account Name: dy627 Account Domain: MyCompany Logon ID: XXXXXXXX Object: Object Server: DS Object Type: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Object Name: %{XXXXXXXX-XXXXXXXX-XXXXXXXX} Handle ID: 0x0 Operation: Operation Type: Object Access Accesses: Write Property Access Mask: 0x20 Properties: Write Property {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX} Additional Information: Parameter 1: - Parameter 2: 123456
'# -split [environment]::NewLine
$ColCount = $InStuff[1].Split(' ').Count
$Collection = $InStuff |
Select-Object -Skip 1 |
ConvertFrom-Csv -Delimiter ' ' -Header
(1..$ColCount).ForEach({"Column_$_"})
$Collection |
Select-Object -Property 'Column_3', 'Column_7'
Output:
$Collection |
Select-Object -Property 'Column_3', 'Column_7'
Column_3 Column_7
-------- --------
13:50:23 Security
13:50:18 Security
13:50:14 Security
Again, I think the issue is just that I don't know how to implement the '-split [environment]::NewLine'command.
$InStuff = Get-Content -Path 'MyCSV.csv' -split [environment]::NewLine
Error:
Get-Content : A parameter cannot be found that matches parameter name 'split'.
Anyway, I hope this sheds some clarity on the issue.

Related

Get-WinEvent and Select-string filter line result

I´m trying to use get-winevent + select string to filter and get the IP from events 4625.
After get-winevent I want to filter the results to show only "Source Network Address:" line, which will provide me the list of IP´s I need to block.
Below is an example of the results, thanks in advance!
PS C:\Users\Administrator> Get-WinEvent -FilterHashtable #{LogName='Security';ID=4625} -MaxEvents 1 | fl
TimeCreated : 15/02/2023 07:43:25
ProviderName : Microsoft-Windows-Security-Auditing
Id : 4625
Message : An account failed to log on.
Subject:
Security ID: S-1-0-0
Account Name: -
Account Domain: -
Logon ID: 0x0
Logon Type: 3
Account For Which Logon Failed:
Security ID: S-1-0-0
Account Name: ADMINISTRATOR
Account Domain:
Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xC000006D
Sub Status: 0xC0000064
Process Information:
Caller Process ID: 0x0
Caller Process Name: -
Network Information:
Workstation Name: -
Source Network Address: 209.45.48.94
Source Port: 0
Detailed Authentication Information:
Logon Process: NtLmSsp
Authentication Package: NTLM
Transited Services: -
Package Name (NTLM only): -
Key Length: 0
Get-WinEvent -FilterHashtable #{LogName='Security';ID=4625} -MaxEvents 100 | Select-String -Pattern "Source Network Address:" tried this way but no results showed
(Get-WinEvent -FilterHashtable #{LogName='Security';ID=4625} -MaxEvents 1).Message.split(':') -split("`t") | ? { $_ -match '\d+\.\d+\.\d+.\d+'} | % {$_ -replace ("`n","")}
As it seems you need to extract an IP-address, I would suggest to use a regex for matching it.
$regex = [regex]::new("\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b")
Get-WinEvent -FilterHashtable #{LogName='Security';ID=4625} -MaxEvents 100 | Foreach {$regex.Match($_.Message).Value}
This code loops through each result which Get-WinEvent returns and checks with the regex for an IP-address in the message property. When no match is found it will return an empty line.
To get information from the Windows Event log, it is cumbersome to try and parse that out of the Message string.
Better look at the XML where the values can be found under their own attribute names:
$result = Get-WinEvent -FilterHashtable #{LogName='Security';ID=4625} -MaxEvents 100 | ForEach-Object {
# convert the event to XML and grab the Event node
$eventXml = ([xml]$_.ToXml()).Event
# output the values from the XML representation
[PsCustomObject]#{
UserName = ($eventXml.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
IpAddress = ($eventXml.EventData.Data | Where-Object { $_.Name -eq 'IpAddress' }).'#text'
EventDate = [DateTime]$eventXml.System.TimeCreated.SystemTime
}
}
Now, if all you want from this is the list of IP addresses, just do
$result.IpAddress
Thank you all, for quick reply!

How to print process ıd in event log?

Im trying to get process id from my Get-Eventlog. I can not parse the process id from the message. How ı can get it from there ? I tried With Select string -Pattern but it did not worked. My powershell code :
$directory = E:\BpLnfgDsc2.txt
$message = Get-EventLog -log Security -InstanceId 4663 -Newest 1 | Where {$_.message -match "Object Name:\s*$directory"} | foreach {$_.Message}
And here is my output:
PS C:\WINDOWS\system32> $message
An attempt was made to access an object.
Subject:
Security ID: Some-id
Account Name: tester
Account Domain: DESKTOP
Logon ID: Some-Id
Object:
Object Server: Security
Object Type: File
Object Name: E:\BpLnfgDsc2.txt
Handle ID: Some-Id
Resource Attributes: S:AI
Process Information:
Process ID: 0xd34
Process Name: C:\Windows\explorer.exe
Access Request Information:
Accesses: %%4423
Access Mask: 0x80
My expected output:
0xd34
You can extend your regex matching pattern a bit more to also capture the process ID and output it with the automatically populated variable $matches.
I've chosen a capture group name for clarity, you could also just use number captured groups. I also added (?s) at the beginning of the pattern to treat the multiline message string as a single line
$message = Get-EventLog -log Security -InstanceId 4663 -Newest 1 |
Where-Object {$_.message -match "(?s)Object Name:\s*$directory.+Process ID:\s+(?<ProcessID>\S+)"} |
ForEach-Object {$matches.ProcessID}

How to do multiple piping with select-string in Powershell

I googled but did not found what I'm looking for.
I have a big file containing list of countries and people. I am aware how to do multiple piping in Linux, but the same way did not work for me in Powershell.
This is what I looked for and got nothing:
Select-String .\file -pattern 'country:[ ]{8}IR' -context 5 | Select-String -pattern 'names'
But if I separate this command into to, like below, works (in which I want to avoid creating a file to search):
Select-String .\file -pattern 'country:[ ]{8}IR' -context 5 > country
Select-String .\file -patern 'names'
*Update 1
Sample data after first grep is:
file:1407215:names: Hadi
file:1407216:company: sample
file:1407217:city: Tehran
file:1407218:district: 8
file:1407219:country: IR
file:1407220:admin: Mahmoud
file:1407221:tech: Hamed
file:1407222:seller: sell#company
file:1407223:status: Active
file:1407224:id: 12456
Select-String doesn't return a [string] (or array of strings) but an object of type [MatchInfo]. The output of a MatchInfo may look like a multi line text but is split in the properties .Context.PreContext, .Line and .Context.PostContext. So you can't use this object directly to pipe it into Select-String again.
However you can cast the output to [String], -split it at the new lines and use Select-String over this array:
$MatchInfo = Select-String $file -pattern 'country:[ ]{8}IR' -context 5
[string]$MatchInfo -split [environment]::NewLine | Select-String -pattern 'names'
From a PowerShell perspective you will be dealing with objects most of the time, it might be a good idea to get the hang of dealing with them, hence this answer can show you an alternative to parsing your file into an array of objects which can be easily manipulated, filtered, sorted and exported into structured data (such as Csv).
Supposing the test.txt looks similar to this:
names: Hadi
company: sample
city: Tehran
district: 8
country: IR
admin: Mahmoud
tech: Hamed
seller: sell#company
status: Active
id: 12456
names: John
company: sample
city: Tehran
district: 8
country: IR
admin: Doe
tech: Hamed
seller: sell#company
status: Disabled
id: 12456
For this particular case we can use a switch with the -File parameter to read the file and the -Regex switch for the conditional clauses to start capturing and outputting the capture data as objects:
$parsed = switch -Regex -File .\test.txt {
# line starts with "names", signal to start capturing
'^names' {
$startcapture = $true
$out = [ordered]#{}
}
# boolean is set to `$true`, capture this line and add it to the ordered dictionary
{ $startcapture } {
$key, $value = $_.Split(':').Trim()
$out[$key] = $value
}
# line starts with "id", signal to output the object, and restart the capture boolean
'^id' {
$startcapture = $false
[pscustomobject] $out
}
}
After parsing the test.txt file with above switch, $parsed would look like this:
names company city district country admin tech seller status id
----- ------- ---- -------- ------- ----- ---- ------ ------ --
Hadi sample Tehran 8 IR Mahmoud Hamed sell#company Active 12456
John sample Tehran 8 IR Doe Hamed sell#company Disabled 12456
Now $parsed can be exported to structured data at ease with Export-Csv and imported back as objects with Import-Csv:
$parsed | Export-Csv parseddata.csv -NoTypeInformation
$csv = Import-Csv parseddata.csv
It can also be filtered very easily a filtering cmdlet such as Where-Object:
# this array of objects where the `country` property value is equal to "IR"
# AND this array of objects where the `names` property value is equal to "Hadi"
$parsed | Where-Object { $_.country -eq 'IR' -and $_.names -eq 'Hadi' }
Which results in:
names : Hadi
company : sample
city : Tehran
district : 8
country : IR
admin : Mahmoud
tech : Hamed
seller : sell#company
status : Active
id : 12456

PowerShell Get-WinEvent Display only first line of Message property?

Getting acquinted with PowerShell, running into myriads of problems (lack of knowledge).
I'm trying to list myself Windows Security Log logged events by count, but I could also use a "friendly" description field which happens to be the first line of the "Message" Property. I can't figure out a way to extract only that.
Thus, I'm running the following to get an overview of events:
PS C:\TEST> Get-WinEvent -FilterHashtable #{logname="security"}| Group-Object id -NoElement | sort count
Count Name
----- ----
1 4724
1 4722
1 1102
1 4725
2 4718
2 6408
2 4739
2 1101
2 5038
2 4737
3 4717
4 6407
4 4731
10 4738
16 1100
19 4781
22 4904
22 4905
35 6406
38 5033
38 5024
39 4826
39 4608
39 4902
40 4735
113 4647
156 4616
239 5059
355 4688
551 4733
557 4732
605 4797
965 5061
977 5058
1647 4798
6364 4907
6759 4634
7000 4648
10950 4799
19407 4672
22049 4624
But what I want is to include the "Description/Message" Column to show what each event ID corresponds to. For example, for event ID the Message Property contains the following value(?):
An attempt was made to reset an account's password.
Subject:
Security ID: S-1-5-18
Account Name: [EDITED]
Account Domain: [EDITED]
Logon ID: 0x3E7
Target Account:
Security ID: [EDITED]
Account Name: Administrator
Account Domain: [EDITED]
Out of this entire Message I'd wish to extract only the following line:
An attempt was made to reset an account's password.
Thus getting back to my original view, ideally it would show the following:
Count Name Message
----- ---- ----
1 4724 An attempt was made to reset an account's password.
1 4722 A user account was enabled.
1 1102 The audit log was cleared.
(...)
Try this:
$Events = Get-WinEvent -FilterHashtable #{logname="security"} | Group-Object id
$Events | Select-Object Count,Name,#{Name='Message';Expression={ (($_.Group.Message | Select -First 1) -Split "`n")[0] }} | Sort-Object Count -Descending | Format-Table -Wrap
Works by removing the -NoElement parameter of Group-Object so that we get the Group result returned, which we can then retrieve the first line of the message property from.
We use Select-Object to add a calculated property to the result that contains the message.
Also using Format-Table -Wrap so the view of the final output doesn't truncate the first line if its long.
Example output:
Count Name Message
----- ---- -------
81 4798 A user's local group membership was enumerated.
13 5379 Credential Manager credentials were read.
5 5061 Cryptographic operation.
1 5058 Key file operation.

Fill multi dimension array with plain text in Powershell

I am working on a Powershell script to monitor a SAN.
I successfully extracted a text file containing all the values from the system in Powershell with this code:
& "NaviSecCli.exe" -user xxxx -password xxxx -h host -f "C:\LUNstate.txt" lun -list
$Path = "C:\LUNstate.txt"
$Text = "Capacity \(GBs\)"
$Name = "^Name"
Get-Content $Path | Select-String -pattern $Text,$Name
This generates the following output:
Name: TEST-DATASTORE-1
User Capacity (GBs): 1536.000
Consumed Capacity (GBs): 955.112
Name: CV Snapshot Mountpoint
User Capacity (GBs): 1024.000
Consumed Capacity (GBs): 955.112
Now I can split the values through the colon, by putting the output into a variable:
$LUNArray = Get-Content $Path | Select-String -pattern $Text,$Name
$LUNArray | foreach {
$LUNArray = $_ -split ': '
Write-Host $LUNArray[0]
Write-Host $LUNArray[1]
}
The only interesting data is stored in $LUNArray[1], so I can just leave out Write-Host $LUNArray[0] which gives me the following output:
TEST-DATASTORE-1
1536.000
955.112
CV Snapshot Mountpoint
1024.000
955.112
Now the tricky part, I would like to put the data into a multi dimensional array. So I would get the following array layout:
LUN Usercap ConsCap
TEST-DATASTORE-1 1536.000 955.112
CV Snapshot Mountpoint 1024.000 955.112
The input file looks like this:
LOGICAL UNIT NUMBER 201
Name: TEST-DATASTORE-1
UID: 60:06:E4:E3:11:50:E4:E3:11:20:A4:D0:C6:E4:E3:11
Current Owner: SP B
Default Owner: SP B
Allocation Owner: SP B
User Capacity (Blocks): 3221225472
User Capacity (GBs): 1536.000
Consumed Capacity (Blocks): 2005641216
Consumed Capacity (GBs): 956.364
Pool Name: Pool HB Hasselt
Raid Type: Mixed
Offset: 0
Auto-Assign Enabled: DISABLED
Auto-Trespass Enabled: DISABLED
Current State: Ready
Status: OK(0x0)
Is Faulted: false
Is Transitioning: false
Current Operation: None
Current Operation State: N/A
Current Operation Status: N/A
Current Operation Percent Completed: 0
Is Pool LUN: Yes
Is Thin LUN: Yes
Is Private: No
Is Compressed: No
Tiering Policy: Lowest Available
Initial Tier: Lowest Available
Tier Distribution:
Capacity: 100.00%
LOGICAL UNIT NUMBER 63920
Name: CV Snapshot Mountpoint
UID: 60:50:38:00:14:50:38:00:C6:64:50:38:00:50:38:00
Current Owner: SP B
Default Owner: SP B
Allocation Owner: SP B
User Capacity (Blocks): 2147483648
User Capacity (GBs): 1024.000
Consumed Capacity (Blocks): 2005641216
Consumed Capacity (GBs): 956.364
Pool Name: Pool HB Hasselt
Raid Type: Mixed
Offset: 0
Auto-Assign Enabled: DISABLED
Auto-Trespass Enabled: DISABLED
Current State: Ready
Status: OK(0x0)
Is Faulted: false
Is Transitioning: false
Current Operation: None
Current Operation State: N/A
Current Operation Status: N/A
Current Operation Percent Completed: 0
Is Pool LUN: Yes
Is Thin LUN: Yes
Is Private: No
Is Compressed: No
Tiering Policy: Lowest Available
Initial Tier: Lowest Available
Tier Distribution:
Capacity: 100.00%
...
$filePath = 'absolute path'
$content = [IO.File]::ReadAllText($filePath)
[regex]::Matches(
$content,
'(?x)
Name: [ ]* ([^\n]+) # name
\n User [ ] (Capacity) [^:]+: [ ]* ([^\n]+) # capacity
\n Consumed [ ] \2 [^:]+:[ ]* ([^\n]+)' # Consumed
) |
ForEach-Object {
$LUN = $_.groups[1].value
$Usercap = $_.groups[3].value
$ConsCap = $_.groups[4].value
# process $Lun, $Usercap and $ConsCap
}
Build a list of custom objects, like this:
& "NaviSecCli.exe" -user xxxx -password xxxx -h host -f "C:\LUNstate.txt" lun -list
$datafile = 'C:\LUNstate.txt'
$pattern = 'Name:\s+(.*)[\s\S]+(User Capacity).*?:\s+(.*)\s+(Consumed Capacity).*?:\s+(.*)'
$LUNArray = (Get-Content $datafile | Out-String) -split '\r\n(\r\n)+' |
Select-String $pattern -AllMatches |
Select-Object -Expand Matches |
% {
New-Object -Type PSObject -Property #{
'LUN' = $_.Groups[1].Value
$_.Groups[2].Value = $_.Groups[3].Value
$_.Groups[4].Value = $_.Groups[5].Value
}
}
The data can be displayed for instance like this:
"{0}: {1}" -f $LUNArray[1].LUN, $LUNArray[1].'Consumed Capacity'