Search code examples
powershellparametersswitch-statementpowershell-5.0

Switch Parameter and an If Statement


I am trying to use the value of a switch parameter as the trigger to write to a csv file if the parameter is called with the script from the command line. However, with my current code the csv file is created whether I include the parameter or not. What's up with that?

Also, is there a better way to handle my else/if else/if else section?

[CmdletBinding()]
param (
    [Parameter(Mandatory=$true)]
    [string]$dir,
    [Parameter(Mandatory=$true)]
    [int]$days,
    [switch]$csv=$false
)

Process {
    Clear-Host
    $totSize = 0
    $totFiles = 0
    $modDate = (Get-date).AddDays(-$days).Date
    $modfiles = Get-ChildItem -Path $dir -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge $modDate } 
    If ($csv = $true){
        $modfiles | Select-Object -Property FullName, Length,LastWriteTime | Export-Csv -Path .\modFiles.csv -NoTypeInformation
    }
    foreach ($file in $modfiles){
        $totFiles = $totFiles + 1
        $totSize = $totSize + $file.Length 
    }

    If ($totSize -lt 1MB){
        $outSize = $totSize/1KB
        $unit = "KB"
    }
    elseif (($totSize -ge 1MB) -and ($totSize -lt 1GB)){
        $outSize = $totSize/1MB
        $unit = "MB"   
    }
    elseif ($totSize -ge 1GB){
        $outSize = $totSize/1GB
        $unit = "GB" 
    } 

    $outRound = [math]::Round($outSize,2)
    Write-Host $totFiles "Files"
    Write-Host $outRound $unit
}

Solution

  • Two problems.

    1. Do not specify a default value for a [switch] parameter. It will mess you up. Leave it off, and it will be $true if specified, and $false if not.
    2. When testing a logical value, such as an If statement, do not use the assignment equals (=), use the comparison equals (-eq).
    If ($csv -eq $true){
        $modfiles | Select-Object -Property FullName, Length,LastWriteTime | Export-Csv -Path .\modFiles.csv -NoTypeInformation
    }
    

    EDIT (Thanks @Scepticalist): Further, if the variable you are testing already holds a [bool] value, or can be implicitly converted to [bool], you don't even need the -eq $true part of the comparison, so:

    If ($csv){
            $modfiles | Select-Object -Property FullName, Length,LastWriteTime | Export-Csv -Path .\modFiles.csv -NoTypeInformation
        }