【问题标题】:Powershell script not recognising FunctionsPowershell脚本无法识别函数
【发布时间】:2015-05-26 07:41:25
【问题描述】:

我编写了以下 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 脚本\FileCleaner.ps1:158 字符:5 + 删除AICXMLLogs $dir + ~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (DeleteAICXMLLogs:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

SendEmail : 术语“SendEmail”未被识别为 cmdlet、函数、脚本文件或可运行的程序。检查拼写 的名称,或者如果包含路径,请验证该路径是 正确并重试。在 C:\Users\pmcma\Documents\Projects\Replace 带有 PowerShell 脚本的 FileCleaner\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 字符:5 + DeleteLogFiles($fileCleanerLogs) + ~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (DeleteLogFiles:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

我认为声明或调用函数的方式没有任何问题。任何想法为什么这个脚本会失败?

【问题讨论】:

    标签: function powershell runtime-error


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      我也遇到过这种情况。尝试将函数放在业务逻辑之前。这是一个脚本,不是编译代码。因此,在您调用它们之前,尚未声明这些函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多