简体   繁体   中英

PowerShell pass a switch to a function with Invoke-Command

I'm having some difficulties passing the switch -CleanFolders to a function by using Invoke-Command. I found this , but I don't really know how to implement it as it's not targeted to a function.

Calling my function like this works fine:

Delete-OldFiles $Target $OlderThanDays $Server -CleanFolders
Invoke-Command -ComputerName "$Server" -Authentication Credssp -Credential $Credentials -ScriptBlock ${Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server)

But this doesn't work at all:

Invoke-Command -ComputerName "$Server" -Authentication Credssp -Credential $Credentials -ScriptBlock ${Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server, -CleanFolders)

Full script:

#__________________________________________________________________________________________________________________________________
$ImportFile = "S:\Input\Scheduled Task\Auto_Clean.csv"
$Password = cat "S:\Input\pwd.txt" | ConvertTo-SecureString -Force
$UserName = "domain\me"

#__________________________________________________________________________________________________________________________________
# Scriptblock for running the function in a job
$JobFunc = {
# Function that removes files older than x days in all subfolders
Function Delete-OldFiles {
<# 
.SYNOPSIS   
    Script to delete files and folders older than x days

.DESCRIPTION
    Remove files older than x days in all subfolders and write success and failure actions to the logfile in "\\DEUSTHEIDIT02\Log\Scheduled Task\Auto_Clean\". 
    By default, empty foldes will be left behind and not deleted.

.PARAMETER Target 
    The path that will be recusively scanned for old files

.PARAMETER OlderThanDays
    Filter for age of file, entered in days. Use 0 for all files to be removed

.PARAMETER CleanFolders
    If this switch is specified folders that are older than 'OlderThanDays' and are empty will be removed. Default behaviour of this script is to leave empty folders behind.

.EXAMPLE
    Delete-OldFiles -Target "\\grouphc.net\bnl\DEPARTMENTS\Brussels\CBR\SHARE\Target" -OlderThanDays "10"
    Delete-OldFiles "\\grouphc.net\bnl\DEPARTMENTS\Brussels\CBR\SHARE\Target" "10"
    Delete-OldFiles "E:\DEPARTMENTS\CBR\SHARE\Target" "10"

Description:
    Deletes all files older than 10 days in the Target folder and all of its subfolders and write success and failure to the log.

.EXAMPLE
    Delete-OldFiles "\\grouphc.net\bnl\DEPARTMENTS\Brussels\CBR\SHARE\Target" "10" -CleanFolders

Description:
    Deletes all files older than 10 days and all empty folders in the Target folder and all of its subfolders and write success and failure to the log.

.NOTES
    REQUIREMENTS Remote server:
    PowerShell 2.0
    As admin run 'Set-ExecutionPolicy RemoteSigned'
    As amdin run 'Enable-WSManCredSSP -Role Server -Force'

    REQUIREMENTS Script server:
    Enable-WSManCredSSP -Role Client -DelegateComputer *.grouphc.net -Force

    CHANGELOG
    2014/05/06 Script born 
    2014/05/07 Added total runtime of the script to the logfile
    2014/05/12 Added timestamps, fail and success messages to the logfile
    2014/05/13 Added PowerShell 2.0 compatibility for Windows Server 2003
    2014/05/13 Added remove empty directories
    2014/05/14 Added comment section on top
    2014/05/15 Added parameters to pass variables $Target and $OlderThanDays
    2014/05/19 Added CSV input file for easy management
    2014/05/20 Created function Delete-OldFiles and Delete-OldFolders
    2014/05/22 Rewrote script for calling functions
    2014/05/23 Added switch -CleanFolders
    2014/06/02 Added password authentication for double hop
    2014/06/03 Added loging capability to different files with timestamps

.AUTHOR 
   Me #>
[CmdletBinding(SupportsShouldProcess=$True)] # Add -WhatIf support for dry run
Param(
    [Parameter(Mandatory=$True,Position=1)]
    [ValidateScript({Test-Path $_})]
    [String]$Target,
    [Parameter(Mandatory=$True,Position=2)]
    [Int]$OlderThanDays,
    [Parameter(Mandatory=$False,Position=3)]
    [String]$Server,
    [switch]$CleanFolders
      )

#__________________________________________________________________________________________________________________________________
# Create logfile with the correct name
# Gets date and reformats to be used in log filename
$TempDate = (get-date).ToString("dd-MM-yyyy")
# Reformats $Target so it can be used in the log filename
$TempFolderPath = $Target -replace '\\','_'
$TempFolderPath = $TempFolderPath -replace ':',''
$TempFolderPath = $TempFolderPath -replace ' ',''
# Combines the date and the path scanned into the log filename
$script:LogFile = "\\DEUSTHEIDIT02\Log\Scheduled Task\Auto_Clean\$Server - $TempFolderPath - $TempDate.log"

#__________________________________________________________________________________________________________________________________
# Check the version of PowerShell
if ($PSVersionTable.PSVersion.Major -ge "3") {

    # PowerShell 3+ Remove files older than (FASTER)
    Get-ChildItem -Path $Target -Recurse -File | 
    Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$OlderThanDays) } | 

        ForEach {
        $Item = $_.FullName
        Remove-Item $Item -Recurse -Force -ErrorAction SilentlyContinue

            # Log succes/failure
            $Timestamp = (Get-Date).ToShortDateString()+" | "+(Get-Date).ToLongTimeString()      
            if (Test-Path $Item) { 
                "$Timestamp | FAILLED: $Server $Item (IN USE)"
            } 
            else { 
                "$Timestamp | REMOVED: $Server $Item" 
            }  
        } | Tee-Object $LogFile -Append }

Else {               

    # PowerShell 2 Remove files older than
    Get-ChildItem -Path $Target -Recurse | 
    Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt (Get-Date).AddDays(-$OlderThanDays) } | 

        ForEach {
        $Item = $_.FullName
        Remove-Item $Item -Recurse -Force -ErrorAction SilentlyContinue

            # Log succes/failure
            $Timestamp = (Get-Date).ToShortDateString()+" | "+(Get-Date).ToLongTimeString()   
            if (Test-Path $Item) { 
                Write-Host "$Timestamp | FAILLED: $Server $Item (IN USE)"
               "$Timestamp | FAILLED: $Server $Item (IN USE)"
            } 
            else { 
                  Write-Host "$Timestamp | REMOVED: $Server $Item"
                 "$Timestamp | REMOVED: $Server $Item"
            }  
        } | Out-File $LogFile -Append } 

#__________________________________________________________________________________________________________________________________
    # Switch -CleanFolders deletes empty folders older than x days
    if ($CleanFolders) {

        # Check the version of PowerShell
        if ($PSVersionTable.PSVersion.Major -ge "3") {

            # PowerShell 3+ Remove empty folders older than (FASTER)
            Get-ChildItem -Path $Target -Recurse -Force -Directory  -ErrorAction SilentlyContinue |
            Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$OlderThanDays) } | 
            Where-Object { (Get-ChildItem -Path $_.FullName -Recurse -Force -File) -eq $null } | 

                ForEach {
                $Item = $_.FullName
                Remove-Item $Item -Recurse -Force -ErrorAction SilentlyContinue

                    # Log succes/failure
                    $Timestamp = (Get-Date).ToShortDateString()+" | "+(Get-Date).ToLongTimeString()
                    if (Test-Path $Item) { 
                        "$Timestamp | FAILLED: $Server $Item (IN USE)" 
                    } 
                    else { 
                        "$Timestamp | REMOVED: $Server $Item" 
                    }  
                } | Tee-Object $LogFile -Append
        }     

        else {

            # PowerShell 2 Remove empty folders older than 
            Get-ChildItem -Path $Target -Recurse -Force -ErrorAction SilentlyContinue | 
            Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | 
            Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$OlderThanDays) } | 

                ForEach {
                $Item = $_.FullName
                Remove-Item $Item -Recurse -Force -ErrorAction SilentlyContinue

                    # Log succes/failure
                    $Timestamp = (Get-Date).ToShortDateString()+" | "+(Get-Date).ToLongTimeString()      
                    if (Test-Path $Item) { 
                        Write-Host "$Timestamp | FAILLED: $Server $Item (IN USE)"
                        "$Timestamp | FAILLED: $Server $Item (IN USE)" 
                    } 
                    else { 
                        Write-Host "$Timestamp | REMOVED: $Server $Item"
                        "$Timestamp | REMOVED: $Server $Item" 
                    }  
                } |  Out-File $LogFile -Append 
        } 
    }
}
}

#__________________________________________________________________________________________________________________________________
# Read input file and ignore all lines starting with #
$File = (Import-Csv -Path $ImportFile -Header "Server", "Target", "OlderThanDays" | Where { $_.Server -NotMatch "#" } )

#__________________________________________________________________________________________________________________________________

# If the UNC Path is provided we will run the script locally else it wil be run on the remote server as a job
Foreach ($_ in $File) {

        # Set easy names
        $Server = $_.Server
        $Target = $_.Target
        $OlderThanDays = $_.OlderThanDays

        if ($Server -eq "UNC")
        {
            Write-Host "UNC Path detected: $Target, $OlderThanDays" -ForegroundColor Yellow
            Start-Job -ScriptBlock {Param($Target, $OlderThanDays, $Server) Delete-OldFiles $Target $OlderThanDays $Server} -InitializationScript $JobFunc -ArgumentList ($Target, $OlderThanDays, $Server) -Name DelFiles
            # Remove empty folders to: Delete-OldFiles $Target $OlderThanDays $Server -CleanFolders
        }
        else
        {
            Write-Host "Local path detected: $Server, $Target, $OlderThanDays" -ForegroundColor Cyan

            $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName,$Password

            $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName,$Password
            Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock {$JobFunc; Delete-OldFiles $Target $OlderThanDays $Server} -ArgumentList ($Target, $OlderThanDays, $Server) #-AsJob -JobName DelFiles

            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock {Delete-OldFiles $args[0] $args[1] $args[2] -CleanFolders:$args[3]} -ArgumentList ($Target, $OlderThanDays, $Server, $true) -AsJob -JobName DelFiles
            # Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock ${Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server)

            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock ${Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server) -AsJob -JobName DelFiles
            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock {Delete-OldFiles $Target, $OlderThanDays, $Server} -ArgumentList ($Target, $OlderThanDays, $Server) #-AsJob -JobName DelFiles
            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock {Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server) #-AsJob -JobName DelFiles
            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock ${Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server)
            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock {$JobFunc} -ArgumentList ($Target, $OlderThanDays, $Server) -AsJob -JobName DelFiles
            #Invoke-Command -ComputerName "$Server.grouphc.net" -Authentication Credssp -Credential $Credentials -ScriptBlock ${Function:Delete-OldFiles} -ArgumentList ($Target, $OlderThanDays, $Server)
        }  
}

Thank you for your help.

Try like this:

$sb = {
  function Delete-OldFiles {
    #...
  }

  Delete-OldFiles $args[0] $args[1] $args[2] -CleanFolders:$args[3]
}

Invoke-Command -ComputerName $Server -Authentication Credssp `
  -Credential $Credentials -ScriptBlock $sb `
  -ArgumentList ($Target, $OlderThanDays, $Server, $true)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM