我有一个基于powershell的文件转换解决方案,包含filesystemwatcher和powershell noexit。我遇到的问题是事件不会在一段时间后触发(我不知道什么时候停止,我只是从生产中接到一个电话),我不知道为什么会这样。 问题基本上是我/如何检查现有活动事件观察者的健康状况。我首先尝试添加控件,如果事件对象存在,这样我就可以每天执行几次powershell脚本,但很快就发现它是powershell会话绑定的,我无法从新的PowerShell会话中获取它。
这是解决方案的基本结构。 (匿名,所以函数等重命名了一点,工作负载逻辑被剥离了,并且在它所说的'...'的地方它不是语法错误)
powershell.exe -NoExit -ExecutionPolicy Bypass -inputformat none -File C:\ | ... | .ps1 WINDOWSTARTUP =“hidden”WAITFORINPUT =“NO”DOS =“YES”
function Test-FileLock {
param ([parameter(Mandatory=$true)][string]$Path)
$oFile = New-Object System.IO.FileInfo $Path
if ((Test-Path -Path $Path) -eq $false)
{
return $false
}
try
{
$oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
if ($oStream)
{
$oStream.Close()
}
$false
}
catch
{
# file is locked by a process.
return $true
}
}
function ConvertType1($sourceFile, $custno, $destFile)
{
$result = "-1"
try {
$OFS = "`r`n"
$data = ""
$data += "..."
$data += $OFS + "`tType=""..."""
# |...|
$data | Out-File $destFile
$result = "Done"
Write-Host $result
}
catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$result = "ConvertType1: " + $ErrorMessage + " - " + $FailedItem
Write-Host $result
}
finally
{
}
return $result
}
function ConvertType2($sourceFile, $custno, $destFile)
{
$result = "-1"
try {
$OFS = "`r`n"
$data = ""
$data += "..."
$data += $OFS + "`tType=""..."""
# |...|
$data | Out-File $destFile
$result = "Done"
Write-Host $result
}
catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$result = "ConvertType2: " + $ErrorMessage + " - " + $FailedItem
Write-Host $result
}
finally
{
}
return $result
}
#$devTest = $true
$devTest = $false
if ($devTest)
{
$logfile = "....LOG"
$monitorFolder = '\\..._transformation\Development\Test\In' # Enter the root path you want to monitor.
$destinationFolder = '\\..._transformation\Development\Test\Out' # Enter the root path you want to monitor.
$filter = '*.*' # You can enter a wildcard filter here.
}
else
{
$logfile = ".....LOG"
$monitorFolder = '\\..._transformation\In' # Enter the root path you want to monitor.
$destinationFolder = '\\..._transformation\Out' # Enter the root path you want to monitor.
$filter = '*.*' # You can enter a wildcard filter here.
}
$fsw = New-Object IO.FileSystemWatcher $monitorFolder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
#Check if eventsubcriber already exists, if it does just terminate script. This way we can schedule this script continously to make sure we always have the watcher in place
#Added note: This does not work because the events are per session and we won't be able to see events from previous sessions.
if($devTest)
{
if(Get-EventSubscriber | Where-Object -Property SourceIdentifier -eq "devTest_...FileCreated") {
Exit
}
Register-ObjectEvent $fsw Created -SourceIdentifier devTest_...FileCreated -Action {
$sourceFilename = $Event.SourceEventArgs.Name
$sourcePathFilename = $Event.SourceEventArgs.FullPath
$sourcePath = split-path $sourcePathFilename
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$destinationFile = (join-path $destinationFolder ([system.io.fileinfo]$sourceFilename).BaseName) + ".wli"
Write-Host "$logTime - The file '$sourcePathFilename' was $changeType at $timeStamp" -fore green
try {
$logTime = (Get-Date -format (Get-culture).DateTimeFormat.UniversalSortableDateTimePattern)
Out-File -FilePath $logfile -Append -InputObject "$logTime - The file '$sourceFilename' was $changeType at $timeStamp"
do {
sleep -seconds 1
$fileLockTest = Test-FileLock $sourcePathFilename
} while ($fileLockTest)
switch ($sourceFilename.ToLower())
{
{($_ -like "*hire*") -or ($_ -like "*change*")} { $result = ConvertType1 $sourcePathFilename 123456 $destinationFile }
{($_ -like "*termination*") -or ($_ -like "*...*")} { $result = ConvertType2 $sourcePathFilename 123456 $destinationFile }
default {$result = "Error. File name is not recognized. File name must |...|"}
}
Write-Host "$logTime - Transformation of file '$sourceFilename': $result"
Out-File -FilePath $logfile -Append -InputObject "$logTime - Transformation of file '$sourceFilename': $result"
Move-Item $sourcePathFilename (join-path $sourcePath "Backup") -force
}
Catch
{
$logTime = (Get-Date -format (Get-culture).DateTimeFormat.UniversalSortableDateTimePattern)
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Move-Item $sourcePathFilename (join-path $sourcePath "Error") -force
Write-Host "$logTime - The file '$sourceFilename' encountered an error during transformation. The error message was $ErrorMessage" -fore red
Out-File -FilePath $logfile -Append -InputObject "$logTime - The file '$sourceFilename' encountered an error during transformation. The error message was $ErrorMessage"
}
}
}
else
{
if(Get-EventSubscriber | Where-Object -Property SourceIdentifier -eq "...FileCreated") {
Exit
}
Register-ObjectEvent $fsw Created -SourceIdentifier ...FileCreated -Action {
$sourceFilename = $Event.SourceEventArgs.Name
$sourcePathFilename = $Event.SourceEventArgs.FullPath
$sourcePath = split-path $sourcePathFilename
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$destinationFile = (join-path $destinationFolder ([system.io.fileinfo]$sourceFilename).BaseName) + ".wli"
Write-Host "$logTime - The file '$sourcePathFilename' was $changeType at $timeStamp" -fore green
try {
$logTime = (Get-Date -format (Get-culture).DateTimeFormat.UniversalSortableDateTimePattern)
Out-File -FilePath $logfile -Append -InputObject "$logTime - The file '$sourceFilename' was $changeType at $timeStamp"
do {
sleep -seconds 1
$fileLockTest = Test-FileLock $sourcePathFilename
} while ($fileLockTest)
switch ($sourceFilename.ToLower())
{
{($_ -like "*hire*") -or ($_ -like "*change*")} { $result = ConvertType1 $sourcePathFilename 123456 $destinationFile }
{($_ -like "*termination*") -or ($_ -like "*...*")} { $result = ConvertType2 $sourcePathFilename 123456 $destinationFile }
default {$result = "Error. File name is not recognized. File name must include information about type of file |...|"}
}
Write-Host "$logTime - Transformation of file '$sourceFilename': $result"
Out-File -FilePath $logfile -Append -InputObject "$logTime - Transformation of file '$sourceFilename': $result"
Move-Item $sourcePathFilename (join-path $sourcePath "Backup") -force
}
Catch
{
$logTime = (Get-Date -format (Get-culture).DateTimeFormat.UniversalSortableDateTimePattern)
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Move-Item $sourcePathFilename (join-path $sourcePath "Error") -force
Write-Host "$logTime - The file '$sourceFilename' encountered an error during transformation. The error message was $ErrorMessage" -fore red
Out-File -FilePath $logfile -Append -InputObject "$logTime - The file '$sourceFilename' encountered an error during transformation. The error message was $ErrorMessage"
}
}
}