简体   繁体   English

Powershell脚本无法识别功能

[英]Powershell script not recognising Functions

I've written the following PS script to delete log files from specific server paths. 我编写了以下PS脚本,以从特定服务器路径中删除日志文件。 I'm a novice to PS but I'm getting some errors with a few of the functions that I have written in this script: 我是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)
}

when debugging I'm getting these errors: 调试时出现以下错误:

DeleteAICXMLLogs : The term 'DeleteAICXMLLogs' is not recognized as the name of a cmdlet, function, script file, or operable program. DeleteAICXMLLogs:术语“ DeleteAICXMLLogs”不能识别为cmdlet,函数,脚本文件或可运行程序的名称。 Check the spelling of the name, or if a path was included, verify that the path is correct and try again. 检查名称的拼写,或者是否包含路径,请验证路径是否正确,然后重试。 At C:\\Users\\pmcma\\Documents\\Projects\\Replace FileCleaner with PowerShell Script\\FileCleaner.ps1:158 char:5 + DeleteAICXMLLogs $dir + ~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (DeleteAICXMLLogs:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException 在C:\\ Users \\ pmcma \\ Documents \\ Projects \\使用PowerShell Script \\ FileCleaner.ps1:158替换FileCleaner char:5 + DeleteAICXMLLogs $ dir + ~~~~~~~~~~~~~~~~ + + CategoryInfo: ObjectNotFound:(DeleteAICXMLLogs:String)[],CommandNotFoundException + FullyQualifiedErrorId:CommandNotFoundException

SendEmail : The term 'SendEmail' is not recognized as the name of a cmdlet, function, script file, or operable program. SendEmail:术语“ SendEmail”不能识别为cmdlet,函数,脚本文件或可运行程序的名称。 Check the spelling of the name, or if a path was included, verify that the path is correct and try again. 检查名称的拼写,或者是否包含路径,请验证路径是否正确,然后重试。 At C:\\Users\\pmcma\\Documents\\Projects\\Replace FileCleaner with PowerShell Script\\FileCleaner.ps1:164 char:5 + SendEmail $emailSubject $emailFrom $emailTo + ~~~~~~~~~ + CategoryInfo : ObjectNotFound: (SendEmail:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException 在C:\\ Users \\ pmcma \\ Documents \\ Projects \\使用PowerShell Script \\ FileCleaner.ps1:164替换FileCleaner char:5 + SendEmail $ emailSubject $ emailFrom $ emailTo + ~~~~~~~~ + + CategoryInfo:ObjectNotFound:( SendEmail:String)[],CommandNotFoundException + FullyQualifiedErrorId:CommandNotFoundException

DeleteLogFiles : The term 'DeleteLogFiles' is not recognized as the name of a cmdlet, function, script file, or operable program. DeleteLogFiles:术语'DeleteLogFiles'不被识别为cmdlet,函数,脚本文件或可运行程序的名称。 Check the spelling of the name, or if a path was included, verify that the path is correct and try again. 检查名称的拼写,或者是否包含路径,请验证路径是否正确,然后重试。 At C:\\Users\\pmcma\\Documents\\Projects\\Replace FileCleaner with PowerShell Script\\FileCleaner.ps1:175 char:5 + DeleteLogFiles($fileCleanerLogs) + ~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (DeleteLogFiles:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException 在C:\\ Users \\ pmcma \\ Documents \\ Projects \\使用PowerShell Script \\ FileCleaner.ps1:175替换FileCleaner char:5 + DeleteLogFiles($ fileCleanerLogs)+ ~~~~~~~~~~~~~ + + CategoryInfo: ObjectNotFound:(DeleteLogFiles:String)[],CommandNotFoundException + FullyQualifiedErrorId:CommandNotFoundException

I don't see anything wrong with how I'm declaring the functions or calling them. 我声明函数或调用它们的方式没有发现任何问题。 Any ideas why this script is failing? 有什么想法为什么这个脚本会失败?

PowerShell Scripts are read from the top to the bottom, so you can't use any references before they are defined, most probably that is why you are receiving errors. PowerShell脚本是从顶部到底部读取的,因此在定义它们之前,您不能使用任何引用,这很可能就是您收到错误的原因。 Try adding your function definition blocks above the point where you call them. 尝试将函数定义块添加到调用它们的位置上方。

Alternatively you can make a function having global scope. 或者,您可以使函数具有全局作用域。 Just preface the function name with the keyword global: like, 只需在函数名称前加上关键字global: like,

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

I've had this happen as well. 我也发生过这种情况。 Try placing the functions before the business logic. 尝试将功能放在业务逻辑之前。 This is a script, not compiled code. 这是一个脚本,而不是编译后的代码。 So the functions are yet to be declared before you are calling them. 因此,在调用函数之前,尚未对其进行声明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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