You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell GUI脚本获取子文件夹报错及远程删SQL dump文件求助

解决PowerShell GUI远程删除SQL Dump文件的报错问题

需求目标

  • 远程删除大型SQL dump文件
  • 启动脚本后选中父文件夹点击OK
  • 再次点击OK进入其子文件夹
  • 选择文件后点击OK完成删除
  • 待删文件位于子文件夹的下一级子目录

报错信息

Get-ChildItem : Cannot find path 'C:\Users\Ujjwal Mandal\@{name=All Documents; Size=6.18 GB}' because it does not exist.
At D:\project\test.ps1:30 char:20
+ $child1= $output | Get-ChildItem | Out-GridView -Title "Select server ...

现有代码

Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$TempFile = [io.path]::GetTempFileName()
$form = New-Object System.Windows.Forms.Form
$form.Text = "Fix low space issue"
$form.size =  New-Object System.Drawing.Size(900,400)
$remdmp = New-Object System.Windows.Forms.Button
$remdmp.Location = New-Object System.Drawing.Size(300,35)
$remdmp.Size = New-Object System.Drawing.Size(300,45)
$remdmp.Text = "Remove dump Files"
$remdmp.Font = [System.Drawing.Font]::new('Microsoft Sans Serif', 10, [System.Drawing.FontStyle]::Bold)
$remdmp.Add_Click({
Remove-Item $TempFile -ErrorAction SilentlyContinue
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$svrs ="TM-ND0276"
$path = "\\TM-ND0276\d$\"
$size = 0
$decimalPlaces = 2
$output = @()
$data=Get-ChildItem -Directory $path | ForEach-Object {
 $size += (Get-ChildItem -Recurse $_.FullName | Measure-Object -Property Length -Sum).Sum
 $output += New-Object PSObject -Property @{
 name = $_.Name
 Size = "{0:N$decimalPlaces} GB" -f ((Get-ChildItem -Recurse $_.FullName | Measure-Object -Property Length -Sum).Sum / 1GB)
 }
}

$output | Sort-Object -Descending -Property Size | Out-GridView -Title "select" -PassThru 
$child1= $output | Get-ChildItem | Out-GridView -Title "Select server name folder you want to delete the dump files from" -PassThru
$child2= $child1 | Get-ChildItem | Out-GridView -Title "Select files you want to delete" -PassThru
if($child2) {
$child2 | Remove-Item -Recurse -Force
$msgbox=[System.Windows.MessageBox]::Show('Dump files have been deleted. Check notepad for available free space in D drive')
$dskspce=Invoke-Command -ComputerName $svrs -ScriptBlock {Get-WmiObject -Class win32_logicaldisk | Format-Table DeviceId, MediaType, @{n="Size";e={[math]::Round($_.Size/1GB,2)}},@{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}} }

$dskspce | Format-Table > $TempFile | Notepad $TempFile
}
else{
$msgbox=[System.Windows.MessageBox]::Show('Action has been cancelled. Script will stop here!')
}
})
$Form.Controls.Add($remdmp)

$QUIT = New-Object 'System.Windows.Forms.Button'
$QUIT.DialogResult = 'OK'
$QUIT.Location = '300, 200'
$QUIT.Margin = '5, 5, 5, 5'
$QUIT.Name = 'buttonOK'
$QUIT.Size = '300, 50'
$QUIT.BackColor ="LightGray"
$QUIT.ForeColor ="black"
$QUIT.Text = '&CLOSE'
$QUIT.Font = [System.Drawing.Font]::new('Microsoft Sans Serif', 10, [System.Drawing.FontStyle]::Bold)
$QUIT.UseCompatibleTextRendering = $True
$QUIT.UseVisualStyleBackColor = $False
$QUIT.Add_Click({$form.Add_FormClosing({$_.Cancel=$false});$form.Close()})    
$QUIT.Show()#$QUIT.Hide()
$form.Controls.Add($QUIT)
$form.showdialog()

问题根源

你说得没错,$output是自定义的PSCustomObject而非System.IO.DirectoryInfo对象,这就是报错的核心原因:

  • Get-ChildItem需要接收路径字符串或DirectoryInfo对象,但你传递的自定义对象会被转换成@{name=...; Size=...}格式的字符串,PowerShell会把这个字符串当成本地路径去查找,自然找不到对应的目录。
  • 代码没有捕获Out-GridView -PassThru的选择结果,直接用原始的$output遍历,导致无法进入用户选中的子文件夹。

修复后的代码

核心修改是保留原始DirectoryInfo对象并附加Size属性,同时每一步都捕获用户的选择结果:

Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$TempFile = [io.path]::GetTempFileName()
$form = New-Object System.Windows.Forms.Form
$form.Text = "Fix low space issue"
$form.size =  New-Object System.Drawing.Size(900,400)
$remdmp = New-Object System.Windows.Forms.Button
$remdmp.Location = New-Object System.Drawing.Size(300,35)
$remdmp.Size = New-Object System.Drawing.Size(300,45)
$remdmp.Text = "Remove dump Files"
$remdmp.Font = [System.Drawing.Font]::new('Microsoft Sans Serif', 10, [System.Drawing.FontStyle]::Bold)
$remdmp.Add_Click({
    Remove-Item $TempFile -ErrorAction SilentlyContinue
    $svrs = "TM-ND0276"
    $path = "\\TM-ND0276\d$\"
    $decimalPlaces = 2

    # 保留原始DirectoryInfo对象,添加Size属性用于显示
    $foldersWithSize = Get-ChildItem -Directory $path | ForEach-Object {
        $totalSize = (Get-ChildItem -Recurse $_.FullName -File | Measure-Object -Property Length -Sum).Sum
        $_ | Add-Member -MemberType NoteProperty -Name "Size" -Value ("{0:N$decimalPlaces} GB" -f ($totalSize / 1GB)) -PassThru
    }

    # 第一步:选择父文件夹
    $selectedParent = $foldersWithSize | Sort-Object -Descending -Property Size | Out-GridView -Title "Select parent folder" -PassThru
    if (-not $selectedParent) {
        [System.Windows.MessageBox]::Show('Action has been cancelled. Script will stop here!')
        return
    }

    # 第二步:进入子文件夹(父文件夹的直接子目录)
    $childFolders = Get-ChildItem -Directory $selectedParent.FullName
    $selectedChild = $childFolders | Out-GridView -Title "Select child folder containing dump files" -PassThru
    if (-not $selectedChild) {
        [System.Windows.MessageBox]::Show('Action has been cancelled. Script will stop here!')
        return
    }

    # 第三步:选择要删除的dump文件(子文件夹下一级的文件)
    $dumpFiles = Get-ChildItem -File $selectedChild.FullName
    $selectedFiles = $dumpFiles | Out-GridView -Title "Select dump files to delete" -PassThru
    if (-not $selectedFiles) {
        [System.Windows.MessageBox]::Show('Action has been cancelled. Script will stop here!')
        return
    }

    # 执行删除并处理结果
    try {
        $selectedFiles | Remove-Item -Force -ErrorAction Stop
        [System.Windows.MessageBox]::Show('Dump files have been deleted. Check notepad for available free space in D drive')
        
        # 获取磁盘空间信息(用Get-CimInstance替代已过时的Get-WmiObject)
        $dskspce = Invoke-Command -ComputerName $svrs -ScriptBlock {
            Get-CimInstance -Class win32_logicaldisk | 
            Format-Table DeviceId, MediaType, 
                @{n="Size";e={[math]::Round($_.Size/1GB,2)}},
                @{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}} -AutoSize
        }
        $dskspce | Out-File -FilePath $TempFile
        Notepad $TempFile
    }
    catch {
        [System.Windows.MessageBox]::Show("Error deleting files: $_")
    }
})
$Form.Controls.Add($remdmp)

$QUIT = New-Object 'System.Windows.Forms.Button'
$QUIT.DialogResult = 'OK'
$QUIT.Location = '300, 200'
$QUIT.Margin = '5, 5, 5, 5'
$QUIT.Name = 'buttonOK'
$QUIT.Size = '300, 50'
$QUIT.BackColor ="LightGray"
$QUIT.ForeColor ="black"
$QUIT.Text = '&CLOSE'
$QUIT.Font = [System.Drawing.Font]::new('Microsoft Sans Serif', 10, [System.Drawing.FontStyle]::Bold)
$QUIT.UseCompatibleTextRendering = $True
$QUIT.UseVisualStyleBackColor = $False
$QUIT.Add_Click({$form.Add_FormClosing({$_.Cancel=$false});$form.Close()})    
$QUIT.Show()
$form.Controls.Add($QUIT)
$form.showdialog()

关键优化点

  1. 保留DirectoryInfo对象:用Add-Member给原始文件夹对象添加Size属性,既保留了路径信息,又能在GridView中显示大小
  2. 捕获用户选择:每一步都获取Out-GridView -PassThru的结果,只有用户选中后才继续流程
  3. 性能优化:避免重复遍历文件夹计算大小,一次计算完成后复用结果
  4. 现代API替代:用Get-CimInstance取代已过时的Get-WmiObject
  5. 错误处理:添加try-catch块捕获删除时的异常,提升脚本稳定性

内容的提问来源于stack exchange,提问作者Ujjawal Mandal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:00:02