I have a variable $Shares
which stores the output of the command net view \\COMPUTERNAME /all 2>&1
. The output looks like as below
Shared resources at \\COMPUTERNAME
Share name Type Used as Comment
-------------------------------------------------------------------------------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
The command completed successfully.
I need to format the output with only the first line (Shared resources at \COMPUTERNAME) and the Share Name column (ADMIN$, C$, IPC$)
How can I do that?
If you are still interested in trying to parse the net view
output after reading through the other answers advising not to and considering the provided alternatives here is one way you can parse the output using header lengths to calculate column widths and using the lengths to parse out the different values.
function Parse-CommandOutput {
param(
$Output
)
# Initialize a variable to store the computer name
$computer = $null
# Remove empty lines from the output
$Output = $Output -notmatch '^[ -]*$'
# Iterate through each line of the output
for ($i = 0; $i -lt $Output.Count; $i++) {
# Check if the line contains the computer name
if ($Output[$i] -match '(?<=Shared resources at \\\\).*') {
$computer = $Matches[0]
}
# Check if the line contains a header for the share information
elseif ($Output[$i] -match ' {2,}') {
# Extract the header line
$header = $Output[$i]
# Split the header into individual items based on double spaces
$headerItems = $header -split '(?<= {2})\b'
# Get the length of each header item
$headerLengths = $headerItems | ForEach-Object { $_.Length }
# Iterate through the subsequent lines until a new header or end of output is reached
for ($i = ($i + 1); $i -lt $Output.Count; $i++) {
# Skip lines that don't contain share information
if ($Output[$i] -notmatch 'the command completed|^ *$') {
# Extract the current line
$line = $Output[$i]
# Initialize a starting position for substring extraction
$start = 0
# Extract values from the line based on header lengths
$values = for ($k = 0; $k -lt $headerLengths.Count; $k++) {
if ($k -lt $headerLengths.Count - 1) {
# Extract a substring based on the current header length
$line.Substring($start, $headerLengths[$k])
# Update the starting position for the next substring
$start += $headerLengths[$k]
} else {
# Extract the remaining part of the line
$line.Substring($start)
}
}
# Create a new PowerShell object to store the extracted information
$result = [ordered]@{}
# Add the computer name to the object if available
if ($computer) { $result.Add('Computername', $computer) }
# Add header-value pairs to the object
for ($j = 0; $j -lt $headerItems.Count; $j++) {
$result.Add($headerItems[$j].Trim(), $values[$j].Trim())
}
# Remove empty entries from the object
$result.Remove('')
# Output the PowerShell object
[pscustomobject]$result
}
}
}
}
}
$result = net view \\localhost /all
# $result = net share
# $result = quser.exe
# $result = netstat -nat
# $result = ROUTE.EXE print #doesn't work
$parsed = Parse-CommandOutput $result
$parsed | Format-Table
Note that this may be broken in the future by some update to the command output.
Output would look something like this
Computername Share name Type Used as Comment
------------ ---------- ---- ------- -------
localhost ADMIN$ Disk Remote Admin
localhost C$ Disk Default share
localhost IPC$ IPC Remote IPC
If you only want computername and share name you can uses Select-Object -Property Computername, 'Share name'
or one of the format cmdlets Format-Table -Property Computername, 'Share name'
, Format-List -Property Computername, 'Share name'
$parsed | Select-Object Computername, 'Share name'
Computername Share name
------------ ----------
localhost ADMIN$
localhost C$
localhost IPC$