PowerShell脚本命令行运行正常,任务计划程序执行时路径错误
PowerShell脚本任务计划路径错误解决方案
问题根源
- 错误的对象处理:脚本中
get-item $media是冗余且错误的操作——$media已经是Get-ChildItem返回的FileInfo对象集合,直接对集合调用Get-Item会导致PowerShell在任务计划上下文里错误解析路径,把文件名误识别为根目录下的文件(如D:\Radio\202303100400.mp4,实际应为D:\Radio\kmox\202303100400.mp4)。 - 路径拼接依赖工作目录:手动拼接路径时未使用绝对路径工具,任务计划默认工作目录与脚本预期不符时会触发异常。
具体修复步骤
1. 修复核心遍历逻辑
将出错的文件夹遍历代码:
foreach ($folder in ((get-item $media).DirectoryName) | Select-Object -Unique){
替换为直接读取FileInfo对象的DirectoryName属性:
foreach ($folder in ($media.DirectoryName | Select-Object -Unique)){
2. 统一使用绝对路径生成
用Join-Path替代手动拼接路径,避免斜杠错误和相对路径问题:
- 修改
$htm_out的赋值:if ($path.FullName -eq $path.Root.FullName){ $title = $title_alt $htm_out = Join-Path -Path $path.FullName -ChildPath "mpx.htm" }else{ $title = $path.BaseName $htm_out = Join-Path -Path $path.FullName -ChildPath "mpx.htm" } - 修改
$rss_out的赋值:$rss_out = Join-Path -Path $folder -ChildPath "$ext.rss"
3. 任务计划配置优化
- 在任务计划的操作选项卡中,设置起始于为
D:\Radio,确保脚本执行工作目录正确。 - 确认任务执行账户拥有
D:\Radio文件夹的读写权限,避免权限不足导致的路径访问失败。
修复后的完整脚本
$path= 'D:\Radio' $site='mysite.com' Set-Location -Path $path if ($path -and $(Try{Test-Path $path.trim()} Catch{}) -and (((get-item $path).Attributes) -match "Directory")){ $path = Get-Item $path } else {Write-Host "mp2rss error: Invalid" ;exit} $media = (Get-ChildItem -path $path -File -Recurse -Filter "*.mp*") | Where-Object ` {$_.extension -in ".mp3",".mp4"} | Sort-Object -Descending -Property LastWriteTime if (!$media.Count){Write-Host "mp2rss error: No Media Found" ;exit} # done verifying function when_long($param){ $param = ($param.AddMinutes(-($param.minute %5)).ToString("h:mmtt ddd, MMM d'th'") -replace '(?<!1)1th$','1st' -replace'(?<!1)2th$','2nd' -replace '(?<!1)3th$','3rd') -replace '(?<=:\d\d)AM','a' -replace '(?<=:\d\d)PM','p' return $param } function when_short($param){ $param = ($param.ToString("ddd"),($param.AddMinutes(-($param.minute %5))).ToString("M/dd h:mmt").ToLower() -join " ") return $param } if ((Get-Volume -DriveLetter $path.ToString().Substring(0,1)).FileSystemLabel){ $title_alt = (Get-Volume -DriveLetter $path.ToString().Substring(0,1)).FileSystemLabel }else{$title_alt = "$env:COMPUTERNAME`($($path.FullName.Substring(0,1))`)"} if ($path.FullName -eq $path.Root.FullName){ $title = $title_alt $htm_out = Join-Path -Path $path.FullName -ChildPath "mpx.htm" }else{ $title = $path.BaseName $htm_out = Join-Path -Path $path.FullName -ChildPath "mpx.htm" } $html = @("<html><head><title>$title</title></head><body>") foreach ($folder in ($media.DirectoryName | Select-Object -Unique)){ $ext = @('mp3','mp4') foreach ($ext in $ext){ if ($media | Where-Object {$_.DirectoryName -in $folder -and $_.Extension -match $ext}){ if ((Get-Item $folder).FullName -ne (Get-Item $folder).Root.FullName){ $title = (Get-Item $folder).BaseName }else{$title = $title_alt} if ($ext -match 'mp4'){$title = "$title [V]"} $url = (([System.Uri]$folder).AbsoluteUri.TrimStart(([System.Uri]($path.ToString())).AbsoluteUri)) if ($url){$url = "$site/$url/"}else{$url = "$site/"} $qty = (($media | Where-Object {$_.DirectoryName -in $folder -and $_.Extension -match $ext}) | Measure-Object).Count $whn = (when_long ($media | Where-Object {$_.DirectoryName -in $folder -and $_.Extension -match $ext} | Select-Object -First 1).CreationTime) $html += "<p><a href=`"http://$url$ext.rss`">$title</a><br>$qty files updated $whn</p>" $rss = @("<rss><channel><title>$title</title>") $rss += "<description>$qty files updated $whn</description>" foreach ($file in ($media | Where-Object {$_.DirectoryName -in $folder -and $_.Extension -match $ext})){ if ($file.BaseName -match "^\d+$"){ if ($file.BaseName -match "^\d{12}$"){ $title = (when_short ([Datetime]::ParseExact($file.BaseName, 'yyyyMMddHHmm', $null))) $dsc = (when_long ([Datetime]::ParseExact($file.BaseName, 'yyyyMMddHHmm', $null))) }else{ $title = (when_short $file.CreationTime) $dsc = (when_long $file.CreationTime) } }else{ $title = $file.BaseName $dsc = (when_long $file.CreationTime) } $rss += "<item><title>$title</title>" $rss += "<description>$dsc</description>" $rss += "<enclosure url=`"http://$url$([uri]::EscapeDataString($file.Name))`"/></item>" } $rss += "</channel></rss>" $rss_out = Join-Path -Path $folder -ChildPath "$ext.rss" if (-not (Test-Path $rss_out) -or (Compare-Object (Get-Content -Path $rss_out) $rss)){Out-File -InputObject $rss -FilePath $rss_out} } } } if (-not (Test-Path $htm_out) -or (Compare-Object (Get-Content -Path $htm_out) $html)){Out-File -InputObject $html -FilePath $htm_out}
内容的提问来源于stack exchange,提问作者mrpaulc
相关产品推荐
相关产品推荐

