PowerShell 脚本速度独立与 Visual Code 内

Posted

技术标签:

【中文标题】PowerShell 脚本速度独立与 Visual Code 内【英文标题】:PowerShell script speed standalone vs within Visual Code 【发布时间】:2021-09-06 15:02:09 【问题描述】:

我有一个简单的 PowerShell 脚本,可以将最近添加的文件列表写入文件。

$fpath = "\\DS1821\video\movies"
$file1 = "C:\Users\brian.w.williams\Desktop\RecentMovie.txt"

if (Test-Path $file1) Remove-Item -Path $file1

Get-ChildItem -Path "$fpath" -File -Recurse -Include "*.eng.srt" |
ForEach-Object 

    $movie = $_.BaseName -replace ".eng",""

    if ( ($_.LastWriteTime.Month -ge 7) -and ($_.LastWriteTime.Year -ge 2021) ) 
        Write-Host $movie " = " $_.LastWriteTime
        Write-Output $movie | Out-file $file1 -append;
    
    

脚本运行良好。但是我注意到在可视代码中运行时脚本运行得更快(几分钟)(即“运行而不调试”)。当我独立运行脚本(即“使用 PowerShell 运行”)时,脚本可能需要数小时才能完成。为什么有区别?我有什么办法可以加快速度吗?我已经尝试映射网络文件夹,但没有任何区别。

【问题讨论】:

听起来您正在体验 Windows PowerShell 5.1(Windows 附带的版本)和 PowerShell 7(VScode 的 PowerShell 扩展附带的版本)之间的差异。 虽然与速度性能无关,但最好为文件创建一个独立于平台的路径。 $File1 = Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop' -AdditionalChildPath 'RecentMovie.txt' 我们还没有收到您的来信.. 作为 SO 新手您可能不知道这一点,但习惯上点击左侧的 图标 accept the answer that best solved your problem .这将帮助其他有类似问题的人更轻松地找到它,并有助于激发人们回答您的问题。 【参考方案1】:

有待改进以帮助代码加速。 首先,在 ForEach 循环中使用Write-HostWrite-Output 追加到文件是非常耗时的。

然后您在 Get-ChildItem 上使用参数 -Include,而您确实想在其中使用 -Filter。 Filter 比 Include 快得多,因为后者只会在之后过滤文件名。 -Filter 但是只能在一个文件名模式上工作,但这正是您在这里所做的。

if(..) 也可以改进为仅比较一个值(日期时间),而不是 LastWriteTime 中的两个单独属性。

试试:

$sourcePath = '\\DS1821\video\movies'
# set a variable to an output file on your desktop
$outputFile = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath 'RecentMovies.txt'
# set the reference date in a variable for faster comparison later
$refdate    = (Get-Date -Year 2021 -Month 7 -Day 1).Date

# get the files, filter on the name ending in '*.eng.srt'
# filter more with Where-Object so you'll get only files newer than or equal to the reference date
# output objects with one calculated property ('MovieName') and the LastWriteTime
$movies = Get-ChildItem -Path $sourcePath -File -Recurse -Filter '*.eng.srt' |
            Where-Object  $_.LastWriteTime -ge $refdate  |
            Select-Object @Name = 'MovieName'; Expression = $_.BaseName -replace '\.eng\.srt$', '.srt',
                          LastWriteTime

# now output what you have collected to file. 
# Set-Content creates a new file or overwrites an existing file
$movies.MovieName | Set-Content -Path $outputFile

# and to screen
$movies | ForEach-Object  Write-Host ('0 = 1' -f $_.MovieName, $_.LastWriteTime.ToString()) 

# or to Out-GridView if you prefer
$movies | Out-GridView -Title 'My Movies'

1.我更改了一些变量名称以使代码更易读 2. 由于-replace 使用正则表达式,您必须用反斜杠转义点。正则表达式还将字符串锚定到 BaseName 的末尾,末尾带有美元符号 ($)

【讨论】:

以上是关于PowerShell 脚本速度独立与 Visual Code 内的主要内容,如果未能解决你的问题,请参考以下文章

powershell 各种CMD Batch,Powershell和Visual Basic脚本文件

无法在 Visual Studio Code 中调试 PowerShell 脚本

从PowerShell设置Visual Studio环境变量

Azure Service Fabric 从 Visual Studio 发布升级 - PowerShell 脚本错误

powershell 测量PowerShell命令或PowerShell脚本的速度

Visual Studio给Powershell 程序创建可视化界面