I don't know why it is doing this but if the first script runs and it doesn't find a file in the $path then it would throw the "Exception calling "Open" with "3" argument(s): "Could not find a part of the path 'D:\Data Report\'." error. So I don't know why but when the first scripts calls the 2nd script then it thinks its running and a file is not there.
So I put in a:
if (Test-Path -Path "$path*") {
working code
}
else
{
exit
}
Powershell error when invoking another script
-
20-07-2023 - |
题
I have two scripts that run fine as seperate scripts, but when I invoke one from the other then I get this error message:
Exception Name: System.Management.Automation.MethodInvocationException Exception Type: Exception Message: Exception calling "Open" with "3" argument(s): "Could not find a part of the path 'D:\Data Report\'.
The script being called is moving files from "D:\Data Report\ to another folder in the D:\ directory.
I only get this error when I run the script below. Any ideas?
try
{
$folder = "D:\Data Report\" # Enter the root path you want to monitor.
$filter = '*.*' # You can enter a wildcard filter here.
#$scriptPath = {D:\"file_transfer.ps1"}
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
#Call the file_transfer.ps1 script
#Invoke-Expression $scriptPath
Invoke-Expression D:\file_transfer.ps1
}
} # end of try
catch #Catch any fatel errors and send an email with description
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$ErrorName = $_.Exception.GetType().FullName
$ExceptionBody = @"
Exception Name: $ErrorName
Exception Type: $FailedItem
Exception Message: $ErrorMessage
"@
Send-MailMessage -SmtpServer "server.com" -From "no-replies@company.com" -To "admin@company.com" -Subject "Fatel Error with Monitor Script" -Body $ExceptionBody
} # end of catch
#
@TheMadTechnician Here is the other script that works on its own.
try
{
$path="D:\Data Report\"
$Miscdir="D:\TEST\Data\Misc"
$dataFolder = "D:\Data Report\*"
$items = Get-ChildItem -Path ($path) -ErrorAction Stop
$ErrorActionPreference= 'silentlycontinue'
# enumerate the items array
foreach ($item in $items)
{
# if the item is NOT a directory, then process it.
if ($item.Attributes -ne "Directory")
{
#Write-Host $item.Name
$filePath = $path+$item.name
}
else #send email and exit without running.
{
Write-Host "$filePath is a directory"
Exit
}
function isFileLocked([string]$LockedPath) {
$file=$filePath
$oFile = New-Object System.IO.FileInfo $LockedPath
# Make sure the path is good
if ((Test-Path -Path $LockedPath) -eq $false)
{
echo "Bad Path"
return $false
}
#Try opening file
$oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
if ($oStream)
{
echo "Got valid stream so file must not be locked"
$oStream.Close()
#Pick ID from file name
$ ID = ($item.name.Split("_")[0])
Write-Host $ ID
$listcsv = import-csv d:\number.csv
foreach($number in $listcsv){
$UNCNumber = $number.UNCNumber
#Write-Host $UNCNumber
ANCNumber = $number.NoseNumber
#Write-Host ANCNumber
ANCNumber = $number.NoseNumber
if ($ ID -eq $UNCNumber)
{
#Check/create ID folder
ANCNumberdir="D:\TEST\Data\ANCNumber"
Write-Host ANCNumber
if (!(Test-Path ANCNumberdir))
{ mkdir ANCNumberdir }
Echo "Nose number found the csv file ANCNumber"
$ IDdir = ANCNumber
Write-Host " id from csv file $ ID" }
}
#Check/create App id folder/system
#Pick App ID from file name
$AppID=($item.name.Split("_")[1])
Write-Host $AppID
$Appiddir="ANCNumberdir\$AppID"
if (!(Test-Path $Appiddir))
{ mkdir $Appiddir
Write-Host $Appiddir
}
Move-Item ($filePath) $Appiddir
return $false
} # end if ($oStream)
else
{
echo "InValid stream so file is locked"
return $true
if (!(Test-Path $Miscdir))
{
mkdir $Miscdir
Write-Host $Miscdir
}
Move-Item $path"*" $Miscdir
}
}# end of function
isFileLocked($filePath)
}
# Send an email if the script ran but a file didn't get moved out of the Data Report folder
If (Test-Path $dataFolder)
{
$DataNumbers = (get-childitem $dataFolder | ?{!($_.PSIsContainer)}).Count
}
# check how many files are in our Misc folder and email
$MiscNumbers = (get-childitem $miscdir | ?{!($_.PSIsContainer)}).Count
If ($MiscNumbers -gt 0)
{
}
} # end of try
catch #Catch any fatel errors and send an email with description
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$ErrorName = $_.Exception.GetType().FullName
$ExceptionBody = @"
Exception Name: $ErrorName
Exception Type: $FailedItem
Exception Message: $ErrorMessage
"@
} # end of catch
finally
{
}
解决方案 2
其他提示
I was about to comment, but I think that would end up too long and hard to read. As Richard said, it seems that your issue is likely coming from using Invoke-Expression
when all you want to do is run the other script. There's two basic ways to do this (and many more considerably more complicated ways), so I'll run them down for you real fast.
Use the Call Operator, &
, to run the script. It would be done as such:
& D:\file_transfer.ps1
It's that simple. That will run the other script, and it will run autonomously of this first script.
The second way is to dot source it, which is very similar to using the Call Operator except that it runs the script in the same session so the other script would have access to the variables and what not that you already have declared. From the looks of your script it isn't needed, but it usually doesn't hurt from my experience. The way you would do that is:
. D:\file_transfer.ps1
Hopefully that clears up running the script without using the Invoke-Expression
cmdlet.
Bonus info! When replying to somebody's comment put an @
in front of their name and it will show them that they have a message.