0

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?

1
  • net.exe returns a array of strings, each element a different line. You will need to parse it to keep the lines and elements you want to keep Commented Nov 14, 2024 at 11:08

3 Answers 3

3

Instead of trying to parse already-formatted output from net view, consider fetching the info directly from WMI:

PS ~> Get-CimInstance Win32_Share
    
Name   Path       Description
----   ----       -----------
ADMIN$ C:\Windows Remote Admin
C$     C:\        Default share
IPC$              Remote IPC

PS ~> Get-CimInstance Win32_Share |ForEach-Object Name
ADMIN$
C$
IPC$
Sign up to request clarification or add additional context in comments.

2 Comments

Hi Mathias thanks for the suggestion. The reason I am using net view is I am running the command on remote computers for which I am facing access issue for the WMI commands
@Biswa Do you have PowerShell Remoting configured in the environment? Invoke-Command { Get-CimInstance Win32_Share} |ForEach-Object Name would do too
2
  • When talking to external programs such as net.exe, PowerShell receives text output, which must then be parsed in order to extract information of interest.

    • This is both cumbersome and brittle, if the external program doesn't offer a (usually opt-in) way to output structured text-based data (such as CSV or JSON), as in the case at hand:
      You're then forced to parse a for-display representation of the output data, which may be ambiguous and/or specific to the current display language, and can conceivably change over time.
  • Therefore, it is always preferable to use PowerShell-native commands, given that their output can be processed using object-oriented techniques, and flexibly (re)formatted with PowerShell's various Format-* cmdlets, such as Format-Table.

    • In the case at hand, PowerShell offers the Get-SmbShare cmdlet.

Therefore:

# Create a CIM session for the target computer(s).
# Note: You may specify *multiple* target computers here, separated with commas
#       (or pass them via a variable containing an array ).
#       Uses WS-MAN by default, but can be configured to use DCOM - details below.
$session = New-CimSession COMPUTERNAME

# Get all network shares published by the target computer(s),
# and format the output as desired.
Get-SmbShare -CimSession $session |
  Format-Table -Property Name `
               -GroupBy @{Name='Shared resources at'; Expression='PSComputerName'} 

Remove-CimSession $session # Clean up.

Sample output:

   Shared resources at: COMPUTERNAME

Name
----
ADMIN$
C$
IPC$
Share1
Share2

Note:

  • New-CimSession creates WS-MAN-based CIM sessions by default, which PowerShell's remoting is also based on; given that modern Windows server editions come with PowerShell remoting enabled by default, you should also be able to target them with CIM sessions.

  • Format-Table is used to produce the desired display format, using the properties of interest of the output objects.

    • By using -GroupBy, with a calculated property (to have a friendlier representation than just PSComputerName: COMPUTERNAME), even output from multiple computers will be properly grouped and formatted.

Comments

1

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$

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.