DarkLite1
DarkLite1

Reputation: 14705

PowerShell Switch parameter requires input

I'm a bit in the dark on what would be best practice. I'm creating a function to delete files older than, but I would like to add a switch called -Remote that is optional, but when you choose to use it, the switch requires mandatory information like $Server to have the whole function below executed on the remote server by using the Invoke-Command.

Something like this:

Delete-OldFiles -Target "\\Share\Dir1" -OlderThanDays "10" -LogName "Auto_Clean.log" -Remote "SERVER1"

The script/function

Function Delete-OldFiles
{
[CmdletBinding()]
Param(
    [Parameter(Mandatory=$True,Position=1)]
    [ValidateScript({Test-Path $_})]
    [String]$Target,
    [Parameter(Mandatory=$True,Position=2)]
    [Int]$OlderThanDays,
    [Parameter(Mandatory=$True,Position=3)]
    [String]$LogName
      )

if ($PSVersionTable.PSVersion.Major -ge "3") {

# PowerShell 3+ Remove files older than (FASTER)
    Get-ChildItem -Path $Target -Exclude $LogName -Recurse -File | 
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$OlderThanDays) } | ForEach {
        $Item = $_.FullName
        Remove-Item $Item -Recurse -Force -ErrorAction SilentlyContinue
        $Timestamp = (Get-Date).ToShortDateString()+" | "+(Get-Date).ToLongTimeString()      
        # If files can't be removed
        if (Test-Path $Item)
            { "$Timestamp | FAILLED: $Item (IN USE)" } 
        else
            { "$Timestamp | REMOVED: $Item" }  
        } | Tee-Object $Target\$LogName -Append } # Output file names to console & logfile at the same time

Else {               

# PowerShell 2 Remove files older than
Get-ChildItem -Path $Target -Exclude $LogName -Recurse | 
    Where-Object { !$_.PSIsContainer -and $_.LastWriteTime -lt (Get-Date).AddDays(-$OlderThanDays) } | ForEach {
        $Item = $_.FullName
        Remove-Item $Item -Recurse -Force -ErrorAction SilentlyContinue
        $Timestamp = (Get-Date).ToShortDateString()+" | "+(Get-Date).ToLongTimeString()      
        # If files can't be removed
        if (Test-Path $Item)
            { 
            Write-Host "$Timestamp | FAILLED: $Item (IN USE)"
            "$Timestamp | FAILLED: $Item (IN USE)"
             } 
        else
            { 
            Write-Host "$Timestamp | REMOVED: $Item"
            "$Timestamp | REMOVED: $Item"
            }  
        } |  Out-File $Target\$LogName -Append } 
}

Delete-OldFiles -Target "\\Share\Dir1" -OlderThanDays "10" -LogName "Auto_Clean.log" 
#Delete-OldFiles "E:\Share\Dir1" "5" "Auto_Clean.log"

When I master this I can make the $LogName (logfile) optional to. Thank you for your help. I'm still new to PowerShell and trying to figure this stuff out.

Upvotes: 2

Views: 12372

Answers (1)

Igor Kudrin
Igor Kudrin

Reputation: 185

You can use parameters like this

Param (
[switch] $Remote = $false,
[string] $server = $( 
    if ($Remote) 
        { 
            Read-Host -Prompt "Enter remote server:" 
        } 
    )
)

In this case, if you call script without -Remote, $server will remain $null.

If you'll call script.ps1 -Remote, it will ask you to enter server name.

If you'll use it like scripts.ps1 -Remote -server "Servername", $server will become Servername.

It can be complicated to wrap function into Invoke-Command based on switch, but you can always use Invoke-Command (it should be as fast as direct command), just use parameters like this

Param (
[switch] $Remote = $false,
[string] $server = $( 
    if ($Remote) 
        { 
            Read-Host -Prompt "Enter remote server:" 
        } 
    else
        {
            "localhost"
        }
    )
)

Upvotes: 6

Related Questions