Repeated confirm prompt

Tagged: 

This topic contains 4 replies, has 2 voices, and was last updated by Profile photo of Wei-Yen Tan Wei-Yen Tan 2 weeks, 5 days ago.

  • Author
    Posts
  • #67887
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Hi Guys,

    I have a request at work to remove files in a particular order.

    I thought I would write this tool as a set of functions and it deletes the way it should do.

    However, I wanted to implement ShouldProcess to be able to do whatif and confirm.

    Whatif works fine with the below code. Does what it is suppose to do.

    However when it comes to confirm it is prompting me over and over even though I select all.

    I read through some of other people online that had similar problems and found that it could have something to do with the fact that I have a foreach loop and cycling through that.

    Also a another thing that i observed is that the examples that I have seen have 1 action where they put the
    if ($pscmdlet.shouldprocess($item))

    I tried taking out the loop but that still didnt work, it couldnt pick up the values in my parameters to variables in the code.

    I have multiple actions. I realise that it could be something of the above...or multiple issues. How can I resolve this issue so that it can honour the all capability?

    I put confirm:$false for new-item and add content to reduce the noise...not quite sure how I can do that better.

    Any help/feedback appreciated.
    Many

    function Remove-CustomFile{
    	[CmdletBinding(ConfirmImpact = 'High',
    						SupportsShouldProcess = $true)]
    	param
    	(
    		[Parameter(Mandatory = $true,
    					  ValueFromPipeline = $true,
    					  ValueFromPipelineByPropertyName = $true,
    					  Position = 0)]
    		[psobject[]]$inputobject
    	)
    	
    	begin
    	{
    		
    	}
    	process
    	{
    		
    		
    		foreach ($item in $inputobject)
    		{
    			$fullpath = $item.fullname
    			$directoryname = $item.DirectoryName
    			$filename = $item.BaseName
    			$content1 = "examplecontent"
    			Write-Verbose "Processing file $filename"
    			
    			
    			if ($pscmdlet.shouldprocess($item))
    			{
    				Remove-Item $fullpath
    				New-Item "$directoryname\$filename.txt" -ErrorAction SilentlyContinue -ItemType file 
                                    -confirm:$false | Out-Null
    				$Pathdirectory = "$directoryname\$filename.txt"
    				$contentfilepath = "$directoryname\$filename.txt"
    				Add-Content -path $contentfilepath -Value $content1
    				Write-Verbose "Creating text file in directory $directoryname "
    				
    			}
    		}
    		
    		
    	}
    }
    
  • #67998
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Yeah, that's more or less the way the implementation works. "All" is a little undefined in that situation, although it depends on whether you're piping information in or providing it on a parameter all at once. How're you running this?

  • #68076
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Thanks for your reply Don,

    So I run it through the pipeline like this:

    Get-Childitem c:\temp | Remove-CustomFile -confirm

    This is how I am writing it.

    I tried to create a custom private helper function so it looks like this:

    
    function Delfile
    {
    	[CmdletBinding()]
    	param
    	(
    		$file
    	)
    	
    	$fullpath = $file.fullname
    	$directoryname = $file.DirectoryName
    	$filename = $file.BaseName
    	$content1 = "$example"
    	Remove-Item $fullpath
    	New-Item "$directoryname\$filename.txt" -ErrorAction SilentlyContinue -ItemType file -Confirm:$false | Out-Null
    	$Pathdirectory = "$directoryname\$filename.txt"
    	$contentfilepath = "$directoryname\$filename.txt"
    	Add-Content -path $contentfilepath -Value $content1 -Confirm:$false
    }
    

    I use this as my process block:

    [CmdletBinding(ConfirmImpact = 'Medium',
    						SupportsShouldProcess = $true)]
    	param
    	(
    		[Parameter(Mandatory = $true,
    					  ValueFromPipeline = $true,
    					  ValueFromPipelineByPropertyName = $true,
    					  Position = 0)]
    		[psobject[]]$inputobject
    	)
    
    	begin
    	{
    
    	}
    	process
    	{
    	
    		$filename = $inputobject.basename
    		$directoryname = $inputobject.directoryname
    		if ($pscmdlet.shouldprocess($inputobject))
    		{
    			 
    			Write-Verbose "Processsing file $filename"
    			Write-Verbose "Creating text file in directory $directoryname "
    			Delfile $inputobject
    			}
    		
    		
    		
    	}
    }
    
    

    I thought it maybe because it maybe because its coming across the pipeline and its doing one by one through the process block....so I thought I will try get-childitem | Remove-item -confirm

    This works...so is there any way that I can get my function to work in the same way? Thanks Don. I am very grateful for your help 🙂

  • #68119
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Yeah, so, you're just running into some design eccentricities. Very moving your ForEach loop into the END{} block instead of PROCESS{}. Basically, just rename PROCESS to END.

  • #68157
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Hi Don,

    Thank you for highlighting that as an issue and taking the time to respond. I tried switching to end process but that still came back with the same problem.

    So I did a bit of reading and found this article by Bartek Bielawski https://becomelotr.wordpress.com/2013/05/01/supports-should-process-oh-really/

    that explains the reason why and how to fix the repeated problem by using boundparameters and manipulating it in a certain way to make it work the way it is intended.

You must be logged in to reply to this topic.