Problems with Parameters

This topic contains 7 replies, has 4 voices, and was last updated by  Rob Simmers 1 month ago.

  • Author
    Posts
  • #102572

    Samuel White
    Participant

    Hello everyone,

    I'm new to PowerShell and am working on my first function. I've been having a hard time puzzling out why I can't properly specify a second parameter here when I try to run my function.

    First off, here is the code. Like I said, this is a learning exercise, so it is very basic. Also, while testing I commented out the "Remove-Item" command.

    function remove-oldfiles {
       [CmdletBinding()]   
       param(
           [parameter(Manadatory=$true,Position=0)] 
           [string]$path
    
           [parameter(Manadatory=$true,Position=1)]
           [int]$days,
       )
    
    Get-ChildItem –Path $path -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-$days))} #| Remove-Item
       
       }

    After I import the module and then run it, I'm getting the following behavior.

    PS C:\users\swhite\Documents\WindowsPowerShell> remove-oldfiles "c:\test1" 30
    remove-oldfiles : A positional parameter cannot be found that accepts argument '30'.
    At line:1 char:1
    + remove-oldfiles "c:\test1" 30
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (:) [remove-oldfiles], ParameterBindingException
        + FullyQualifiedErrorId : PositionalParameterNotFound,remove-oldfiles

    Also, something that is very odd to me is that although I specified the property of Mandatory=$true, the second parameter isn't being required. I know this because if I run with just a path the function works.

    Thanks in advance for your assistance.

  • #102574

    Don Jones
    Keymaster

    Commas.

           [parameter(Manadatory=$true,Position=0)] 
           [string]$path,
    
           [parameter(Manadatory=$true,Position=1)]
           [int]$days
    
    • #102575

      Samuel White
      Participant

      That's what I get for moving things around while troubleshooting. I mixed up the placement of that comma.

      Pasting my code into here did point out that I had the work "mandatory" spelled incorrectly. (corrected below)

      I have script with the comma in the correct place is still fails.

      function remove-oldfiles {
         [CmdletBinding()]   
         param(
             [parameter(Mandatory=$true,Position=0)] 
             [string]$path,
      
             [parameter(Mandatory=$true,Position=1)]
             [int]$days
         )
      Get-ChildItem –Path $path -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-$days))} #| Remove-Item
         }

      I still get the error about: A positional parameter cannot be found that accepts argument...

  • #102577

    Don Jones
    Keymaster

    Try running it and using the parameter names.

    remove-oldfiles -path "c:\test1" -days 30

    Positional parameters are for losers :).

    Also, make sure you're running this in a "fresh" session. E.g., if you've loaded this function into the console, it won't re-read the file just because you've made changes. The old one will still be in memory messing with you.

    • #102581

      Samuel White
      Participant

      Reloading a fresh session fixed my problem.

      I had been doing this in the PowerShell ISE and just importing the module again and again.

      I'm certain that in many earlier iterations of the script I had lots of problems.

      Thanks for your help, I really though I was going crazy.

  • #102578

    James Crompton
    Participant

    In your first code you are missing a comma after the 1st parameter and have an unnecessary one after the second parameter which may be causing this behavior.

    function remove-oldfiles {
       [CmdletBinding()]   
       param(
           [parameter(Manadatory=$true,Position=0)] 
           [string]$path , #< -- Comma was missing here.
    
           [parameter(Manadatory=$true,Position=1)]
           [int]$days
       )
    
    Get-ChildItem –Path $path -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-$days))} #| Remove-Item
       
       }
    
  • #102583

    Don Jones
    Keymaster

    Ditch the ISE. Switch to VS Code. ISE has odd ideas about scope that cause me no end of stupid mistakes :).

  • #102587

    Rob Simmers
    Participant

    You're not showing how you are calling the function, but the error message indicates that you are providing more than 2 parameters. This could be:

    Remove-OldFiles C:\Scripts 5 22
    Remove-OldFile C:\My Scripts 33

    For the first scenario, you are provide 22 and it doesn't know what to do with it. The second is most likely what you are doing which is providing a path with a space, so it would see it as 3 params in that example. It should be "C:\My Scripts" to pass it as a string.

    Here is an updated function with some basics. Write-Verbose is your friend. It allows you to show troubleshooting information or run silently just by having the -Verbose switch or no switch respectively. Usually, when you are using functions, you want to gather additional information about what is happening. If you just piped directly to Remove-Item, you don't know what is being removed, so in the function you can split things up so that you can get verbose information if required

    function Remove-OldFiles {
        [CmdletBinding()]   
        param(
            [parameter(Mandatory=$true,Position=0)] 
            [string]$Path,
            [parameter(Mandatory=$true,Position=1)]
            [int]$Days
        )
        begin{}
        process{
            $files = Get-ChildItem –Path $Path -Recurse | 
            Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-$Days))}
    
            Write-Verbose ("Found {0} files to be deleted" -f $files.Count)
            foreach ($file in $files) {
                Write-Verbose ("Removing file {0}." -f $file.FullName)
                $file | Remove-Item -Recurse -Confirm:$false -WhatIf
            }
        }
        end{}
    }
    
    #Use named params
    Remove-OldFiles -Path C:\Scripts -Days 30 -Verbose
    #Use positional params
    Remove-OldFiles C:\Scripts 30
        
    

You must be logged in to reply to this topic.