PowerShell: Copy-Item throws DriveNotFoundException - exception

My script keeps bugging me with the following exception
copy-item : Cannot find drive. A drive with the name 'F' does not exist.
At C:\Program Files (x86)\CA\ARCserve Backup\Templates\RB_Pre_Process.ps1:58 char:1
+ copy-item -Path $drive -Destination $DST_DRIVE -Recurse -ErrorAction Stop
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (F:String) [Copy-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
This is what my script looks like. I am mounting an ISO image on drive F: and I have added a "start-slepp -s 5" command so i can verify the image get's mounted, which it does!
$BACKUP_PATH = "E:\00_BACKUP_DATA"
$DR_PATH = "E:\01_DR_DATA"
$ISO_IMAGE = "C:\Program Files (x86)\CA\ARCserve Backup\Templates\Winpe_x64.iso"
$DST_DRIVE = "E:\"
try {
New-EventLog -LogName Application -Source "RB_Pre_Process.ps1" -ErrorAction Stop
} catch [System.InvalidOperationException] {
Write-host $_
}
try {
Write-Host "Preparing RDX cartridge..."
# Query for disk object
$disk_number = (Get-Disk | Where-Object -Property FriendlyName -like "TANDBERG RDX*").Number
# Remove partitions
Get-Disk $disk_number | Clear-Disk -RemoveData -Confirm:$false | Out-Null
# Create new partition
New-Partition -DiskNumber $disk_number -UseMaximumSize | Out-Null
# Format partition
Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel "RDX_TAPE" -Confirm:$false | Out-Null
# Set partition as active
Set-Partition -DriveLetter E -IsActive:$true | Out-Null
} catch {
Write-Host $_
Write-EventLog -LogName Application -Source $MyInvocation.MyCommand.Name -EventID 2 -Message $_
}
try {
Write-Host "Creating folder structure..."
new-item -itemtype directory -Path $BACKUP_PATH -ErrorAction stop | Out-Null
new-item -itemtype directory -path $DR_PATH -ErrorAction stop | Out-Null
} catch {
Write-Host $_
Write-EventLog -LogName Application -Source $MyInvocation.MyCommand.Name -EventID 2 -Message $_
}
try {
Write-Host "Mounting ISO image..."
$image = Mount-DiskImage -ImagePath $ISO_IMAGE -PassThru -ErrorAction Stop
} catch [ParameterBindingException] {
Write-Host $_
Write-EventLog -LogName Application -Source $MyInvocation.MyCommand.Name -EventId 2 -Message $_
}
$drive = ($image | Get-Volume).DriveLetter
$drive += ":\*"
Start-Sleep -s 5
try {
Write-Host "Copying ISO content..."
copy-item -Path $drive -Destination $DST_DRIVE -Recurse -ErrorAction Stop
} catch {
Write-Host $_
Write-EventLog -LogName Application -Source $MyInvocation.MyCommand.Name -EventId 2 -Message $_
}
try {
Write-Host "Unmounting ISO image..."
Dismount-DiskImage -ImagePath $ISO_IMAGE -ErrorAction Stop
} catch [System.Exception] {
Write-Host $_
Write-EventLog -LogName Application -Source $MyInvocation.MyCommand.Name -EventId 2 -Message $_
}
So, what's going wrong here? Sometimes it works sometimes not...

I "solved" the issue... my script is working perfectly fine when it's getting started directly from the PowerShell prompt instead of the PowerShell ISE... So the IDE is the culprit.

it seems the mounted image can't be reached in powershell. I think it's a limitation of the provider. A possible workaround is issuing CMD command. You could replace
copy-item -Path $drive -Destination $DST_DRIVE -Recurse -ErrorAction Stop
with
& cmd /C "copy F:\* G:\dest\"
Here I just give an example, you may need to do further work to copy recursively..you could use the xcopy or robocopy which could handle recursive copy.

Related

Exporting a computer list with OS version and up/down pings

I'm writing a script in PowerShell-ISE that allows me to ping a computer list and exports the pings associated with each computer as well as the OS version into a CSV. Below is what I got so far. I'm not exactly sure where to put the Test-Connection in here.
$good = "C:\Users\1521599002A\Desktop\good.csv"
$bad = "C:\Users\1521599002A\Desktop\bad.csv"
$Computers = Import-Csv -Path "C:\Users\1521599002A\Desktop\complist.txt" -Header "Name"
foreach ($Computer in $Computers) {
try {
Get-ADComputer -Identity $Computer.Name -Properties Name, operatingSystem |
Select Name, operatingSystem
Out-File -FilePath $good -InputObject "$Computer" -Append -Force
} catch {
$Computer.Name + " not in AD"
Out-File -FilePath $bad -InputObject "$Computer" -Append -Force
}
}

Function not Returning Data

I am using PowerShell to compare the file count and size (per file extension) in 2 separate directories.
$User = $env:username
$pwd = pwd
clear
write-host "`n"
write-host "`n"
write-host "`n"
write "The current user is: $User"
write-host "`n"
write "The current path is: $pwd"
write-host "`n"
write-host "`n"
write-host "`n"
write "We need to know the following information:"
write "`n"
write "`n"
$UserDesktopPath = Read-Host "New PC User Desktop Path" # This should be the new PC Desktop Path
$UserDocumentPath = Read-Host "New PC User Document Path" # This should be the new PC Document Path
$USBDesktopPathServer = Read-Host "USB User Desktop Path" # This should be the USB User Desktop Path
$USBDocumentPathServer = Read-Host "USB User Document Path" # This should be the USB User Document Path
clear
write-host "`n"
write-host "`n"
write-host "`n"
write "This is the results for your Desktop Folder Paths:"
write-host "`n"
$folder_new = Get-ChildItem -Recurse -path "$USBDesktopPathServer" # Recurses the New PC Desktop
$folder_old = Get-ChildItem -Recurse -path "$UserDesktopPath" # Recurses the USB Backup Desktop
Compare-Object -ReferenceObject "$folder_new" -DifferenceObject "$folder_old" # Compares the two folders for the path to identify discrepancies
write-host "`n"
write "This is the results for your Documents Folder Paths:"
write-host "`n"
write-host "`n"
write-host "`n"
$folder_new1 = Get-ChildItem -Recurse -path "$UserDocumentPath" # Recurses the New PC Documents
$folder_old1 = Get-ChildItem -Recurse -path "$USBDocumentPathServer" # Recurses the USB Backup Documents
Compare-Object -ReferenceObject "$folder_new1" -DifferenceObject "$folder_old1" # Compares the two folders for the path to identify discrepancies
write-host "`n"
write-host "`n"
write-host "`n"
write "Now we shall compare file sizes of your Documents:"
write-host "`n"
write-host "`n"
write-host "`n"
write-host "`n"
function doc{
$DirectoryDocuments = "$USBDocumentPathServer", "$UserDocumentPath"
foreach ($Directory in $DirectoryDocuments) {
Get-ChildItem -Path $Directory -Recurse |
Where-Object {-not $_.PSIsContainer} |
Tee-Object -Variable Files |
Group-Object -Property Extension |
Select-Object -Property #{
n = "Directory"
e = {$Directory}
},
#{
n = "Extension"
e = { $_.Name -replace '^\.' }
},
#{
n = "Size (MB)"
e={ [math]::Round( ( ( $_.Group | Measure-Object Length -Sum ).Sum / 1MB ), 2 ) }
},
Count
$Files |
Measure-Object -Sum -Property Length |
Select-Object -Property #{
n = 'Extension'
e = { 'Total' }
},
#{
n = 'Size (MB)'
e = { [math]::Round( ( $_.Sum / 1MB ), 2 ) }
},
Count
}
}
When using the ISE and calling dtop I get the correct return:
PS C:\Users\Michael Nancarrow> dtop
Directory Extension Size (MB) Count
--------- --------- --------- -----
D:\Deployment Kit\Test\Desktop2 txt 0 1
Total 0 1
D:\Deployment Kit\Test\Desktop1 txt 0 11
Total 0 11
Yet when run in the script, it does not return any value. I have attempted to call a function write $tst which runs dtop and that does the same (writes null).
Furthermore, I have removed the { so it does not run as a function, and it operates without an issue. My concern is perhaps the -Path file cannot be parsed at the same time as the input - meaning: when I call dtop from ISE it already has the $Directory variable stored in memory.
Are there any obvious errors here? I am rather new to PowerShell and am unsure where the mistake lies.

I am new to powershell Deploy Chrome it drops a folder on the remote machine then sits in the "Installing update" and never finishes

Variables
$computernames = Get-Content "C:\psexec\Chrome.txt"
$computernames = "NMOTC-sb10-9020"
$sourcefile = "\nmotc-ap-sccm\nmotc_packages\Chrome\googlechromestandaloneenterprise.msi"
This section will install the software
foreach ($computer in $computernames)
{
$destinationFolder = "\\$computer\c$\Program Files\Google"
#This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it.
if (!(Test-Path -path $destinationFolder))
{
Write-Host -ForegroundColor yellow Creating Directory $computer\c$\Program Files\google\application\Chrome
New-Item $destinationFolder -Type Directory
}
Write-Host -ForegroundColor Yellow Copying Update
Copy-Item -Path $sourcefile -Destination $destinationFolder
Write-Host -ForegroundColor Yellow Installing Update
Invoke-Command -ComputerName $computer -ScriptBlock {& cmd /c msiexec.exe -ArgumentList "i C:\Program Files\google\Chrome\googlechromestandaloneenterprise.msi"
}
Write-Host -ForegroundColor Yellow Cleaning Up Installation Files
#Remove-Item $destinationFolder -recurse
}
If you run your code that's in your ScriptBlock locally on a machine you want to install Chrome on does it work? I've used:
msiexec.exe /i "C:\Software\Chrome\GoogleChromeStandaloneEnterprise64.msi" /q /norestart
That command has worked for me when running it locally in PowerShell, seems like that should work in your ScriptBlock as well.
Variables
$computernames = Get-Content "C:\psexec\Chrome.txt"
$computernames = "xxxx-sb10-3020"
$sourcefile = "\nmotc-ap-sccm\xxxx_packages\Chrome\googlechromestandaloneenterprise.msi"
This section will install the software
foreach ($computer in $computernames)
{
$destinationFolder = "\\$computer\c$\Program Files\Chrome"
#This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it.
if (!(Test-Path -path $destinationFolder))
{
Write-Host -ForegroundColor yellow Creating Directory $computer\c$\Windows\System32\11.0.19
New-Item $destinationFolder -Type Directory
}
Write-Host -ForegroundColor Yellow Copying Update
Copy-Item -Path $sourcefile -Destination $destinationFolder
Write-Host -ForegroundColor Yellow Installing Update
Invoke-Command -ComputerName $computer -ScriptBlock { & cmd /c msiexec.exe /i "C:\Program Files\Chrome\GoogleChromeStandaloneEnterprise.msi"
}
Write-Host -ForegroundColor Yellow Cleaning Up Installation Files
Remove-Item $destinationFolder -recurse
}
I did get this to work well

How can i uninstall Google Chrome using Power Shell

I am working towards writing a powershell script for uninstalling the current version 54.0.2840.99 m of Google Chrome from my machine but could not be able to do so. I am using the following piece of code in my script:
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match “Google Chrome”}
$app.Uninstall()
The chrome is installed in my machine but the above code is not showing Google Chrome in the list. It is returning null value and it could not be able to uninstall.
Could you please tell me where i have been went wrong or any other alternative solution for uninstalling the Google Chrome via PowerShell?
Google Chrome doesn't use WMI when installing chrome. You can use the command below to find the version, and uninstall chrome using its setup package.
(Get-ItemProperty -path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome').version | ForEach-Object {& ${env:ProgramFiles(x86)}\Google\Chrome\Application\$_\Installer\setup.exe --uninstall --multi-install --chrome --system-level --force-uninstall}
I use this:
$GoogleChrome = [CimInstance](Get-CimInstance -ClassName Win32_Product | Where-Object {$_.Name -eq 'Google Chrome'})
If ($GoogleChrome -ne $null) {
Write-Host 'Uninstalling Google Chrome'$GoogleChrome.Version
Invoke-CimMethod -InputObject $GoogleChrome -MethodName 'Uninstall' | Out-Null
}
The search for the uninstaller takes longer than I would like, but it works for the 64-bit version of Google Chrome we use.
There might have been some changes with Chrome that gave me some trouble with the solutions above. This worked for me just recently, and it will work with some other software packages too. It also gives a good basis for confirming the package is no longer installed:
$target_computers='computer1','computer2','computer3'
$software_to_remove='chrome'
Get-PSSession | Remove-PSSession
$target_sessions=New-PSSession -ComputerName $target_computers
if ($software_to_remove -Like 'chrome') {
Invoke-Command -Session (Get-PSSession) -ScriptBlock{
$computer_name=$env:COMPUTERNAME
$chrome_installed_object=(Get-ItemProperty -path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome')
if ($chrome_installed_object -ne $null) {
$chrome_version=($chrome_installed_object | select-object -ExpandProperty Version)
$chrome_uninstaller_string=($chrome_installed_object | Select-Object -ExpandProperty UninstallString)
$chrome_uninstaller_full_string=($chrome_uninstaller_string+" --force-uninstall")
Write-Host "For $computer_name, we have found the following version of Chrome: $chrome_version"
Write-Host "Removing version $chrome_version"
Write-Host "This is the Chrome uninstall string we are using: $chrome_uninstaller_full_string"
cmd.exe /c $chrome_uninstaller_full_string
}
}
}
Invoke-Command -Session (Get-PSSession) -ScriptBlock{
param($software_to_remove)
$computer_name=$env:Computername
#Look at installed programs
Write-Host ("Looking for a package matching this pattern: "+$software_to_remove+" on server "+$computer_name)
$program_to_remove = $(Get-WmiObject -Class Win32_Product | Where-Object -Property Name -Like "*$software_to_remove*")
if (![string]::IsNullOrWhiteSpace($program_to_remove)) {
Write-Host "These programs have been located: $program_to_remove"
$oktoremove=$(Read-Host "OK to remove these programs (y or n)?")
If (!($oktoremove -eq 'y')) {
Write-Host 'Exiting the entire script on server $computer_name since you do not wish to take any further action now'
exit
}
$program_to_remove.Uninstall()
}
#Look at installed packages
$PackageToRemove=$(Get-Package -Provider Programs -IncludeWindowsInstaller | Where-Object -Property Name -Like "*$software_to_remove*")
$PackageToRemove_name=$(Get-Package -Provider Programs -IncludeWindowsInstaller | Where-Object -Property Name -Like "*$software_to_remove*" | Select-Object -ExpandProperty Name)
if (![string]::IsNullOrWhiteSpace($PackageToRemove)) {
Write-Host "$PackageToRemove_name"
$oktoremove=$(Read-Host "OK to remove software (y or n)?")
If (!($oktoremove -eq 'y')) {
Write-Host 'Exiting the entire script on server $computer_name since you do not wish to take any further action now'
exit
}
Uninstall-Package -Name $PackageToRemove -Verbose -Force
}
#Just in case the previous approach did not remove the package successfully, use the GUID this time
Get-Package -Provider Programs -IncludeWindowsInstaller | Where-Object -Property Name -Like "*$software_to_remove*" | Uninstall-Package
#Check again, just to make sure
$x86Path = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$installedItemsX86 = Get-ItemProperty -Path $x86Path | Select-Object -Property PSChildName, DisplayName, DisplayVersion
$x64Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
$installedItemsX64 = Get-ItemProperty -Path $x64Path | Select-Object -Property PSChildName, DisplayName, DisplayVersion
$installedItems = $installedItemsX86 + $installedItemsX64
$installedItems | Where-Object -FilterScript { $null -ne $_.DisplayName } | Sort-Object -Property DisplayName | ft
} -ArgumentList($software_to_remove)

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?
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
}
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.