Search code examples
powershellverbosenew-item

Powershell: What's the right way to output full error messages from New-Item?


I'm running a vagrant winrm command, and am noticing that a command that fails doesn't print out the entire error output... I thought | might be used to expand output from such commands... but after some internet searching, and trying a few options, such as:

  • | fl
  • | Format-Table -Wrap -Au

I still get a ... in the final output of my error message, i.e. in the part where the command is echo'd.

NewItemIOError
At line:1 char:1
+ New-Item -path C:\var\lib\kubelet\etc\kubernetes\pki\ -type SymbolicL ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The above failure is happening for a clear and obvious reason, so I don't need help debugging the issue, but rather, am generally wondering what is the right option to use with New-Item to make sure powershell shows me the entire output of its failed execution in automated environments with 10000s of lines of logs.

What's the simplest way to output verbose error messages from new-item, and similar powershell commands?


Solution

  • Simply put - dots in exception message in console are only for display purposes - to not give you wall of text. If you want to display the FULL exception you can use something like this:

    try {
        New-Item NONEXISTING:\asd.txt -ErrorAction Stop #This will throw error
        Write-Host "If it shows error was not caught"
    }
    catch {
        $_.Exception | Format-List -Force
    }
    

    This displays info like below and gives you full info about Exception object :)

    ErrorRecord                 : Cannot find drive. A drive with the name 'NONEXISTING' does not exist.
    ItemName                    : NONEXISTING
    SessionStateCategory        : Drive
    WasThrownFromThrowStatement : False
    Message                     : Cannot find drive. A drive with the name 'NONEXISTING' does not exist.
    Data                        : {}
    InnerException              :
    TargetSite                  : System.Management.Automation.PSDriveInfo GetDrive(System.String, Boolean)
    StackTrace                  :    at System.Management.Automation.SessionStateInternal.GetDrive(String name, Boolean automount)
                                     at System.Management.Automation.SessionStateInternal.GetDrive(String name, Boolean automount)
                                     at System.Management.Automation.LocationGlobber.GetDriveRootRelativePathFromPSPath(String path, CmdletProviderContext context, Boolean escapeCurrentLocation, PSDriveInfo& workingDriveForPath, CmdletProvider& providerInstance)
                                     at System.Management.Automation.LocationGlobber.GetProviderPath(String path, CmdletProviderContext context, Boolean isTrusted, ProviderInfo& provider, PSDriveInfo& drive)
                                     at System.Management.Automation.SessionStateInternal.NewItem(String[] paths, String name, String type, Object content, CmdletProviderContext context)
                                     at Microsoft.PowerShell.Commands.NewItemCommand.ProcessRecord()
    HelpLink                    :
    Source                      : System.Management.Automation
    HResult                     : -2146233087
    

    For full message or stack trace, just go with $_.Exception.Message or $_.Exception.StackTrace:

    try {
        New-Item NONEXISTING:\asd.txt -ErrorAction Stop; #This will throw error
        Write-Host "If it shows error was not caught"
    }
    catch {
        Write-Host "MESSAGE`n$($_.Exception.Message)"
        Write-Host "STACK TRACE`n$($_.Exception.StackTrace)"
    }
    

    and it gives info:

    MESSAGE
    Cannot find drive. A drive with the name 'NONEXISTING' does not exist.
    STACK TRACE
       at System.Management.Automation.SessionStateInternal.GetDrive(String name, Boolean automount)
       at System.Management.Automation.SessionStateInternal.GetDrive(String name, Boolean automount)
       at System.Management.Automation.LocationGlobber.GetDriveRootRelativePathFromPSPath(String path, CmdletProviderContext context, Boolean escapeCurrentLocation, PSDriveInfo& workingDriveForPath, CmdletProvider& providerInstance)
       at System.Management.Automation.LocationGlobber.GetProviderPath(String path, CmdletProviderContext context, Boolean isTrusted, ProviderInfo& provider, PSDriveInfo& drive)
       at System.Management.Automation.SessionStateInternal.NewItem(String[] paths, String name, String type, Object content, CmdletProviderContext context)
       at Microsoft.PowerShell.Commands.NewItemCommand.ProcessRecord()
    

    PS. If you want even more info:

    try {
        New-Item NONEXISTING:\asd.txt -ErrorAction Stop
        Write-Host "If it shows error was not caught"
    }
    catch {
        $_ | Format-List -Force
    }
    

    This will display all the info including ScriptStackTrace (at which line the exception occurred):

    Exception             : System.Management.Automation.DriveNotFoundException: Cannot find drive. A drive with the name 'NONEXISTING' does not exist.
                               at System.Management.Automation.SessionStateInternal.GetDrive(String name, Boolean automount)
                               at System.Management.Automation.SessionStateInternal.GetDrive(String name, Boolean automount)
                               at System.Management.Automation.LocationGlobber.GetDriveRootRelativePathFromPSPath(String path, CmdletProviderContext context, Boolean escapeCurrentLocation, PSDriveInfo& workingDriveForPath, CmdletProvider& providerInstance)
                               at System.Management.Automation.LocationGlobber.GetProviderPath(String path, CmdletProviderContext context, Boolean isTrusted, ProviderInfo& provider, PSDriveInfo& drive)
                               at System.Management.Automation.SessionStateInternal.NewItem(String[] paths, String name, String type, Object content, CmdletProviderContext context)
                               at Microsoft.PowerShell.Commands.NewItemCommand.ProcessRecord()
    TargetObject          : NONEXISTING
    CategoryInfo          : ObjectNotFound: (NONEXISTING:String) [New-Item], DriveNotFoundException
    FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.NewItemCommand
    ErrorDetails          :
    InvocationInfo        : System.Management.Automation.InvocationInfo
    ScriptStackTrace      : at <ScriptBlock>, <No file>: line 2
    PipelineIterationInfo : {}
    PSMessageDetails      :