none
Why is -Verbose not working with Invoke-Command? RRS feed

  • Question

  • I have the following script:

        try {
            Invoke-Command -Computer $Server -ScriptBlock { Get-ChildItem -Path $Directory | 
            Where {$_.Name -Match "$DB"} | 
            Remove-Item -confirm:$false -Recurse $VerbosePreference='Continue'; -Verbose } #-Verbose
    
            Write-Host "`r`nsuccessfull! " -foregroundcolor yellow -backgroundcolor black
        }
        catch {
            write-host "`r`nFAILED!" -foregroundcolor red -backgroundcolor black
            Write-Host "$($error[0])`r`n" -foregroundcolor magenta -backgroundcolor black
        }

    -verbose is not generating any verbose like this:

    VERBOSE: Performing the operation "Remove File" on target ...

    if i try the following command:

    Get-ChildItem -Path 'E:\' | Where{$_.Name -Match "text"} | Remove-Item -confirm:$false -Recurse
     -Verbose

    I actually get back:

    VERBOSE: Performing the operation "Remove File" on target "E:\text.xml".

    VERBOSE: Performing the operation "Remove File" on target "E:\text.txt".

    according to this thread:

    How to Write-Verbose from Invoke-Command?

    I am supposed to use $VerbosePreference='Continue';

    but i already tried that as you can see and still i cant get verbose to output anything!

    also, even though no folders get deleted, apparently, my try catch STILL outputs that it was successfull...

    how come?

    Thursday, April 4, 2019 12:27 AM

Answers

  • You have to pass parameters into the script block:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
        Get-ChildItem -Path $dir | 
            Where {$_.Name -Match "$name"} | 
                Remove-Item -confirm:$false -Recurse -Verbose 
    } -ArgumentList $Directory, $DB

    I'm pretty sure the reason you see nothing from the -Verbose is because the Get-Childitem didn't find anything.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    • Marked as answer by cataster Thursday, April 4, 2019 1:19 AM
    Thursday, April 4, 2019 12:51 AM

All replies

  • You have to pass parameters into the script block:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
        Get-ChildItem -Path $dir | 
            Where {$_.Name -Match "$name"} | 
                Remove-Item -confirm:$false -Recurse -Verbose 
    } -ArgumentList $Directory, $DB

    I'm pretty sure the reason you see nothing from the -Verbose is because the Get-Childitem didn't find anything.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    • Marked as answer by cataster Thursday, April 4, 2019 1:19 AM
    Thursday, April 4, 2019 12:51 AM
  • You have to pass parameters into the script block:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
        Get-ChildItem -Path $dir | 
            Where {$_.Name -Match "$name"} | 
                Remove-Item -confirm:$false -Recurse -Verbose 
    } -ArgumentList $Directory, $DB

    I'm pretty sure the reason you see nothing from the -Verbose is because the Get-Childitem didn't find anything.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    instead of saying delete successful...can i tell it to say "no files exist with that name"...? i mean how can i make it successful if it deletes and just no file exists status if there truly is nothing to delete?
    • Edited by cataster Thursday, April 4, 2019 1:01 AM
    Thursday, April 4, 2019 1:00 AM
  • I have the following script:

    try {
    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
        Get-ChildItem -Path $dir | 
            Where {$_.Name -Match "$name"} | 
                Remove-Item -confirm:$false -Recurse -Verbose 
    } -ArgumentList $Directory, $DB
    
        Write-Host "`r`nsuccessfull! " -foregroundcolor yellow -backgroundcolor black
    }
    catch {
        write-host "`r`nFAILED!" -foregroundcolor red -backgroundcolor black
        Write-Host "$($error[0])`r`n" -foregroundcolor magenta -backgroundcolor black
    }

    if no files exist to delete...it currently still says "successful" as output...can i refine this to say "there was no files to delete" else "successfully deleted x number of files"?

    also, the recurse on verbose is needed because otherwise i am forced to manually confirm even with confirm parameter. I think its because there are many sub items inside the target folder(s) i am looking to delete...

    however, i get a TON of verbose messages for every single one of those items saying

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem1

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem2

    can i make it so that it just prints verbose on a folder level instead for every single item?

    VERBOSE: Performing the operation "Remove Directory" on target \name1

    • Merged by jrvModerator Thursday, April 4, 2019 1:43 AM DUPLICATE
    Thursday, April 4, 2019 1:22 AM
  • You have to pass parameters into the script block:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
        Get-ChildItem -Path $dir | 
            Where {$_.Name -Match "$name"} | 
                Remove-Item -confirm:$false -Recurse -Verbose 
    } -ArgumentList $Directory, $DB

    I'm pretty sure the reason you see nothing from the -Verbose is because the Get-Childitem didn't find anything.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    I created a link since that is considered another question i believe

    https://social.technet.microsoft.com/Forums/en-US/ac5f038c-fcef-4101-90bb-35fe9cfe8d10/how-to-test-getchilditem-for-no-files-as-part-of-invokecommand?forum=winserverpowershell

    Thursday, April 4, 2019 1:23 AM
  • Sure. Here's one way:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
    
        $f = Get-ChildItem -Path $dir | Where {$_.Name -Match "$name"}
        If ($f) {
            $f | Foreach {
                Remove-Item $_ -confirm:$false -Recurse -Verbose 
            }
        }
        else {
            Write-Verbose "No file found"
        }
    } -ArgumentList $Directory, $DB
    That Get-ChildItem isn't restricted to only file names. It'll also find directories whose names match. Is that why you included the -Recurse parameter on the Remove-Item? If you don't intend to remove directories, then adding the "-File" parameter to the Get-ChildItem will prevent the removal of directories. However, if you did intend to remove directories then someone can use this with the values of "c:\" and "*" and remove every directory on the C: drive they have permission to remove.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Thursday, April 4, 2019 1:35 AM
  • Sure. Here's one way:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
    
        $f = Get-ChildItem -Path $dir | Where {$_.Name -Match "$name"}
        If ($f) {
            $f | Foreach {
                Remove-Item $_ -confirm:$false -Recurse -Verbose 
            }
        }
        else {
            Write-Verbose "No file found"
        }
    } -ArgumentList $Directory, $DB
    That Get-ChildItem isn't restricted to only file names. It'll also find directories whose names match. Is that why you included the -Recurse parameter on the Remove-Item? If you don't intend to remove directories, then adding the "-File" parameter to the Get-ChildItem will prevent the removal of directories. However, if you did intend to remove directories then someone can use this with the values of "c:\" and "*" and remove every directory on the C: drive they have permission to remove.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    actually i want to remove both folders(directories) AND files as long as they match the $name. so yes its intended. 

    btw, i get a TON of verbose messages for every single one of those items saying

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem1

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem2

    can i make it so that it just prints verbose on a folder level instead for every single item?

    VERBOSE: Performing the operation "Remove Directory" on target \name1

    Thursday, April 4, 2019 1:39 AM
  • Sure. Here's one way:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
    
        $f = Get-ChildItem -Path $dir | Where {$_.Name -Match "$name"}
        If ($f) {
            $f | Foreach {
                Remove-Item $_ -confirm:$false -Recurse -Verbose 
            }
        }
        else {
            Write-Verbose "No file found"
        }
    } -ArgumentList $Directory, $DB
    That Get-ChildItem isn't restricted to only file names. It'll also find directories whose names match. Is that why you included the -Recurse parameter on the Remove-Item? If you don't intend to remove directories, then adding the "-File" parameter to the Get-ChildItem will prevent the removal of directories. However, if you did intend to remove directories then someone can use this with the values of "c:\" and "*" and remove every directory on the C: drive they have permission to remove.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    I have been trying this snippet for a while and it kept trying to look for the files in the C:\ drive...why is it defualting to C even though i am specifying a directory somewhere else? I just realized your comment about this says someone can use this with the values of "c:\" and "*" and remove every directory on the C: drive they have permission to remove.
    Thursday, April 4, 2019 5:27 AM
  • Sure. Here's one way:

    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
    
        $f = Get-ChildItem -Path $dir | Where {$_.Name -Match "$name"}
        If ($f) {
            $f | Foreach {
                Remove-Item $_ -confirm:$false -Recurse -Verbose 
            }
        }
        else {
            Write-Verbose "No file found"
        }
    } -ArgumentList $Directory, $DB
    That Get-ChildItem isn't restricted to only file names. It'll also find directories whose names match. Is that why you included the -Recurse parameter on the Remove-Item? If you don't intend to remove directories, then adding the "-File" parameter to the Get-ChildItem will prevent the removal of directories. However, if you did intend to remove directories then someone can use this with the values of "c:\" and "*" and remove every directory on the C: drive they have permission to remove.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    I have been trying this snippet for a while and it kept trying to look for the files in the C:\ drive...why is it defualting to C even though i am specifying a directory somewhere else? I just realized your comment about this says someone can use this with the values of "c:\" and "*" and remove every directory on the C: drive they have permission to remove.

    found out why:

    https://stackoverflow.com/a/55509366/8397835

    I am supposed to have Remove-Item $_.FullName

    Thursday, April 4, 2019 6:48 AM
  • Changing the line:

    Remove-Item $_ -confirm:$false -Recurse -Verbose

    to:

    $_ | Remove-Item -confirm:$false -Recurse -Verbose

    Should work, too.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, April 5, 2019 1:46 AM
  • Changing the line:

    Remove-Item $_ -confirm:$false -Recurse -Verbose

    to:

    $_ | Remove-Item -confirm:$false -Recurse -Verbose

    Should work, too.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Some of the files get deleted...

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem1

    VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem2

    but others throwout this error following the other verbose messages:

    Cannot remove item d:\temp\name1.db\metadata.sqlitedb: The process cannot access the file 'metadata.sqlitedb' because it is being used by another process.

    Directory d:\temp\name1.db cannot be removed because it is not empty.

    How can i automatically kill the process used (whichever it is) and attempt to remove the item again as part of my script above?

    looking for something like this:

    $Directory = "d:\temp"
    Invoke-Command -Computer $Server -ScriptBlock { 
        param ($dir, $name)
    
    #Write-Output "dir='$dir', name='$name'"
    
    $f = Get-ChildItem -Path $dir | Where {$_.Name -Match $name} | Select -ExpandProperty FullName
    if ($f) {
        $f | Foreach {
                    try
                {
                    Remove-Item $_ -confirm:$false -recurse -Verbose #-WhatIf
                }
                catch
                {
                    if ($_.Exception.Message -like '*it is being used by another process*')
                    { write-host "that process is " $pid + $pname
                        try{
                            KILL PROCESS
                            Remove-Item $_ -confirm:$false -recurse -Verbose #-WhatIf
                        }
                        catch
                        {
                            $error[0]
                        }
    
                    }
                    else
                    {
                        Write-Host "$($error[0])`r`n" -foregroundcolor magenta -backgroundcolor black
                    }
                }
        }
    }
    else {
        Write-Verbose "No file found"
    }
    } -ArgumentList $Directory, $DB -verbose

    Friday, April 5, 2019 2:43 AM