PowerShell使用Invoke-Command将开关传递给函数

时间:2014-06-03 09:32:16

标签: powershell

我在使用Invoke-Command将switch -CleanFolders传递给函数时遇到了一些困难。我找到this,但我真的不知道如何实现它,因为它不是针对某个函数。

调用我的函数可以正常工作:

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

但这根本不起作用:

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

完整脚本:

#__________________________________________________________________________________________________________________________________
$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)
        }  
}

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

试试这样:

$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)