Powershell脚本无法识别函数

时间:2015-03-23 10:40:01

标签: function powershell runtime-error

我编写了以下PS脚本来删除特定服务器路径中的日志文件。我是PS的新手,但是我在这个脚本中编写的一些函数出现了一些错误:

#* FileName: FileCleaner.ps1
#Clear the screen
Clear

#Read XML Config File to get settings
[xml]$configfile = Get-Content "C:\Users\pmcma\Documents\Projects\Replace FileCleaner with PowerShell Script\FileCleaner.config.xml"

#Declare and set variables from Config values
$hostServer = $configfile.Settings.HostServer
$dirs = @($configfile.Settings.DirectoryName.Split(",").Trim())
$scanSubDirectories = $configfile.Settings.ScanSubDirectories
$deleteAllFiles = $configfile.Settings.deleteAllFiles
$fileTypesToDelete = @($configfile.Settings.FileTypesToDelete.Split(";").Trim())
$liveSiteLogs = $configfile.Settings.LiveSiteLogs
$fileExclusions = @($configfile.Settings.FileExclusions.Split(";").Trim())
$retentionPeriod = $configfile.Settings.RetentionPeriod
$AICLogs = $configfile.Settings.AICLogs
$AICLogsRententionPeriod = $configfile.Settings.AICLogsRententionPeriod
$fileCleanerLogs = $configfile.Settings.FileCleanerLogs
$fileCleanerLogsRententionPeriod = $configfile.Settings.FileCleanerLogsRententionPeriod

#Setup FileCleaner output success logfiles
$successLogfile = $configfile.Settings.SuccessOutputLogfile
$dirName  = [io.path]::GetDirectoryName($successLogfile)
$filename = [io.path]::GetFileNameWithoutExtension($successLogfile)
$ext = [io.path]::GetExtension($successLogfile)
$successLogfile = "$dirName\$filename$(get-date -Format yyyy-MM-dd)$ext"

#Setup FileCleaner output error logfiles
$errorLogfile = $configfile.Settings.ErrorOutputLogfile
$dirName  = [io.path]::GetDirectoryName($errorLogfile)
$filename = [io.path]::GetFileNameWithoutExtension($errorLogfile)
$ext = [io.path]::GetExtension($errorLogfile)
$errorLogfile = "$dirName\$filename$(get-date -Format yyyy-MM-dd)$ext"

#Setup Retention Period        
$LastWrite = (Get-Date).AddDays(-$retentionPeriod)#.ToString("d") 
$AICLastWrite = (Get-Date).AddDays(-$AICLogsRententionPeriod)#.ToString("d")
$fileCleanerLastWrite = (Get-Date).AddDays(-$fileCleanerLogsRententionPeriod)

#EMAIL SETTINGS
$smtpServer = $configfile.Settings.SMTPServer
$emailFrom = $configfile.Settings.EmailFrom
$emailTo = $configfile.Settings.EmailTo
$emailSubject = $configfile.Settings.EmailSubject
#Update the email subject to display the Host Server value
$emailSubject -replace "HostServer", $hostServer 

$countUnaccessibleUNCPaths = 0

#Check Logfiles exists, if not create them
if(!(Test-Path -Path $successLogfile))
{
    New-Item -Path $successLogfile –itemtype file
}

if(!(Test-Path -Path $errorLogfile))
{
    New-Item -Path $errorLogfile  –itemtype file
}

foreach ($dir in $dirs) 
{
#needs a check to determine if server/the UNC Path is accessible. If it fails to connect, it needs to move on to the next UNC share but a flag needs to 
#be generate to alert us to investigate why the UNC share was not accessible during the job run.
If(Test-Path -Path $dir)
{
    #write to output logfile Directory info
    $Msg = Write-Output "$(Get-Date -UFormat "%D / %T") - Accessing: $dir"
    $Msg | out-file $successLogfile

    If ($scanSubDirectories -eq "True") 
    {
        If ($deleteAllFiles -eq "True") 
        {
            #ScanSubDirectories and delete all files older than the $retentionPeriod, include Sub-Directories / also forces the deletion of any hidden files
            $logFiles = Get-ChildItem -Path $dir -Force -Recurse -Exclude $fileExclusions[0],$fileExclusions[1] | Where { $_.LastWriteTime -le "$LastWrite" }
            DeleteLogFiles($logFiles)
            #foreach($logFile in $logFiles)
            #{
            #    if($logFile -ne $null)
            #    {
            #        $Msg = Write-Output "$("Deleting File $logFile")" 
            #        $Msg | out-file $successLogfile -append 
            #        Remove-Item $logFile.FullName -Force
            #    }
            #}                                                             
        } 
        Else 
        {
            #"ScanSubDirectories but only delete specified file types."
            $logFiles = Get-Childitem $dir -Include $fileTypesToDelete[0],$fileTypesToDelete[1],$fileTypesToDelete[2], $liveSiteLogs -Recurse -Exclude $fileExclusions[0],$fileExclusions[1] | Where {$_.LastWriteTime -le "$LastWrite"}
            DeleteLogFiles($logFiles)
            #foreach($logFile in $logFiles)
            #{
            #    if($logFile -ne $null)
            #    {
            #        $Msg = Write-Output "$("Deleting File $logFile")" 
            #        $Msg | out-file $successLogfile -append 
            #        Remove-Item $logFile.FullName -Force
            #    }
            #}  
        }   
    } 
    Else 
    {
        #Only delete files in top level Directory
        If ($deleteAllFiles -eq "True") 
        {
            $logFiles = Get-ChildItem -Path $dir -Force -Exclude $fileExclusions[0],$fileExclusions[1] | Where { $_.LastWriteTime -le "$LastWrite" }
            DeleteLogFiles($logFiles)
            #foreach($logFile in $logFiles)
            #{
            #    if($logFile -ne $null)
            #    {
            #        $Msg = Write-Output "$("Deleting File $logFile")" 
            #        $Msg | out-file $successLogfile -append 
            #        Remove-Item $logFile.FullName -Force
            #    }
            #}
        } 
        Else 
        {
            $logFiles = Get-Childitem $dir -Include $fileTypesToDelete[0],$fileTypesToDelete[1],$fileTypesToDelete[2], $liveSiteLogs -Exclude $fileExclusions[0],$fileExclusions[1] | Where {$_.LastWriteTime -le "$LastWrite"}
            DeleteLogFiles($logFiles)
            #foreach($logFile in $logFiles)
            #{
            #    if($logFile -ne $null)
            #    {
            #        $Msg = Write-Output "$("Deleting File $logFile")" 
            #        $Msg | out-file $successLogfile -append 
            #        Remove-Item $logFile.FullName -Force
            #    }
            #}     
        }     
    }
}
Else
{
    $countUnaccessibleUNCPaths++        
    #server/the UNC Path is unaccessible   
    $Msg = Write-Output  "$(Get-Date -UFormat "%D / %T") Unable to access $dir."  
    $Msg | out-file $errorLogfile -append        
}  
# Call the function to Delete the AIC XML Logfiles
DeleteAICXMLLogs $dir   
}
#If any of the directories were unaccessible send an email to alert the team
if($countUnaccessibleUNCPaths.count -gt 0) 
{
# Call the function to send the email
SendEmail $emailSubject $emailFrom $emailTo
}

#Only keep 2 weeks worth of the FileCleaner App logs for reference purposes
If(Test-Path -Path $fileCleanerLogs)
{
#write to output logfile Directory info
$Msg = Write-Output "$(Get-Date -UFormat "%D / %T") - Accessing: $fileCleanerLogs"
$Msg | out-file $successLogfile

$fileCleanerLogs = Get-Childitem $fileCleanerLogs -Recurse | Where {$_.LastWriteTime -le "$fileCleanerLastWrite"}
DeleteLogFiles($fileCleanerLogs)
#foreach($fileCleanerLog in $fileCleanerLogs)
#{
#    if($fileCleanerLog -ne $null)
#    {
#        $Msg = Write-Output "$("Deleting File $fileCleanerLog")" 
#        $Msg | out-file $successLogfile -append 
#        Remove-Item $fileCleanerLog.FullName -Force
#    }
#}                
}

Function DeleteLogFiles($logFiles)
{
    foreach($logFile in $logFiles)
    {
        if($logFile -ne $null)
        {
        $Msg = Write-Output "$("Deleting File $logFile")" 
        $Msg | out-file $successLogfile -append 
        Remove-Item $logFile.FullName -Force
        }
    }
}

Function DeleteAICXMLLogs($dir)
{
    #Split the UNC path $dir to retrieve the server value
    $parentpath = "\\" + [string]::join("\",$dir.Split("\")[2])
    #test access to the \\server\D$\DebugXML path
    If(Test-Path -Path $parentpath$AICLogs)
    {
        $Msg = Write-Output "$(Get-Date -UFormat "%D / %T") - Accessing: $parentpath$AICLogs"
        $Msg | out-file $successLogfile

        #Concantenate server value to $AICLogs to delete all xml logs in \\server\D$\DebugXML with a retention period of 30Days
        $XMLlogFiles = Get-ChildItem -Path $parentpath$AICLogs -Force -Include $fileTypesToDelete[3]-Recurse -Exclude $fileExclusions[0],$fileExclusions[1] | Where { $_.LastWriteTime -le "$AICLastWrite" }
        #get each file and add the filename to be deleted to the successLogfile before deleting the file 
        DeleteLogFiles($XMLlogFiles)
    #foreach($XMLlogFile in $XMLlogFiles)
    #{
    #    if($XMLlogFile -ne $null)
    #    {
    #        $Msg = Write-Output "$("Deleting File $XMLlogFile")" 
    #        $Msg | out-file $successLogfile -append 
    #        Remove-Item $XMLlogFile.FullName -Force
    #    }
    #}      
}
Else
{
    $Msg = Write-Output "$("$parentpath$AICLogs does not exist.")"
    $Msg | out-file $successLogfile -append   
}
}

Function SendEmail($emailSubject, $emailFrom, $emailTo)
{       
    $MailMessage = New-Object System.Net.Mail.MailMessage
    $SMTPClient = New-Object System.Net.Mail.smtpClient
    $SMTPClient.host = $smtpServer
    $Recipient = New-Object System.Net.Mail.MailAddress($emailTo, "Recipient")
    $Sender = New-Object System.Net.Mail.MailAddress($emailFrom, "Sender")

    $MailMessage.Sender = $Sender
    $MailMessage.From = $Sender
    $MailMessage.Subject = $emailSubject        
    $MailMessage.Body = @"
    This email was generated because the FileCleaner script was unable to access some UNC Paths, please refer to $errorLogfile for more information. 

Please inform the Team if you plan to resolve this.

This is an automated email please do not respond.
"@
    $SMTPClient.Send($MailMessage)
}

调试时我遇到了这些错误:

  

DeleteAICXMLLogs:术语'DeleteAICXMLLogs'不被识别为   cmdlet,函数,脚本文件或可运行程序的名称。   检查名称的拼写,或者如果包含路径,请验证   路径是正确的,然后再试一次。在   C:\ Users \ pmcma \ Documents \ Projects \用PowerShell替换FileCleaner   Script \ FileCleaner.ps1:158 char:5   + DeleteAICXMLLogs $ dir   + ~~~~~~~~~~~~~~~~       + CategoryInfo:ObjectNotFound:(DeleteAICXMLLogs:String)[],CommandNotFoundException       + FullyQualifiedErrorId:CommandNotFoundException

     

SendEmail:“SendEmail”一词不会被识别为a的名称   cmdlet,函数,脚本文件或可操作程序。检查拼写   如果包含名称,或者包含路径,请验证路径是否正确   正确,然后再试一次。在C:\ Users \ pmcma \ Documents \ Projects \ Replace   FileCleaner与PowerShell Script \ FileCleaner.ps1:164 char:5   + SendEmail $ emailSubject $ emailFrom $ emailTo   + ~~~~~~~~~       + CategoryInfo:ObjectNotFound:(SendEmail:String)[],CommandNotFoundException       + FullyQualifiedErrorId:CommandNotFoundException

     

DeleteLogFiles:“DeleteLogFiles”一词不被识别为   cmdlet的名称,函数,脚本文件或可运行的程序。校验   名称的拼写,或者如果包含路径,请验证   路径是正确的,然后再试一次。在   C:\ Users \ pmcma \ Documents \ Projects \用PowerShell替换FileCleaner   Script \ FileCleaner.ps1:175 char:5   + DeleteLogFiles($ fileCleanerLogs)   + ~~~~~~~~~~~~~~       + CategoryInfo:ObjectNotFound:(DeleteLogFiles:String)[],CommandNotFoundException       + FullyQualifiedErrorId:CommandNotFoundException

我没有看到我如何声明功能或调用它们有什么问题。任何想法为什么这个脚本失败?

2 个答案:

答案 0 :(得分:4)

PowerShell脚本从上到下读取,因此您无法在定义之前使用任何引用,这很可能就是您收到错误的原因。 尝试在您调用它们的位置上方添加功能定义块。

或者,您可以创建具有全局范围的函数。只需在函数名称前加上关键字 global:,例如

function global:test ($x, $y)
{
    $x * $y 
}

答案 1 :(得分:2)

我也发生了这种情况。尝试在业务逻辑之前放置函数。这是一个脚本,而不是编译代码。因此,在调用函数之前,函数尚未声明。