paulmcm
paulmcm

Reputation: 93

Powershell script not recognising Functions

I've written the following PS script to delete log files from specific server paths. 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:

#* 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. 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

SendEmail : The term 'SendEmail' is not recognized as the name of a cmdlet, function, script file, or operable program. 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

DeleteLogFiles : The term 'DeleteLogFiles' is not recognized as the name of a cmdlet, function, script file, or operable program. 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

I don't see anything wrong with how I'm declaring the functions or calling them. Any ideas why this script is failing?

Upvotes: 1

Views: 3416

Answers (2)

Abdullah Leghari
Abdullah Leghari

Reputation: 2470

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. 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,

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

Upvotes: 6

SDillon
SDillon

Reputation: 313

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.

Upvotes: 2

Related Questions