powershellformattingsmbfileshare

Formatting output of PowerShell


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?


Solution

  • 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$