Author Posts

April 4, 2017 at 5:16 pm

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 "
				
			}
		}
		
		
	}
}

April 5, 2017 at 3:55 pm

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?

April 6, 2017 at 10:09 am

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 🙂

April 6, 2017 at 1:49 pm

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.

April 6, 2017 at 4:29 pm

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.