AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题

问题[powershell](coding)

Martin Hope
Simon Elms
Asked: 2025-04-28 19:32:17 +0800 CST

在 PowerShell 中创建不使用构造函数的 .NET 类型的实例

  • 9

我有一个用于在 IIS 中设置网站的 PowerShell 脚本。它包含以下功能:

function Set-IisWebsiteBinding (
    [Parameter(Mandatory = $true)]
    [string]$SiteName, 
    
    [Parameter(Mandatory = $true)]
    [Microsoft.Web.Administration.Site]$Website,
    
    [Parameter(Mandatory = $true)]
    [array]$WebsiteBindingSettings
)
{
    # Set up website bindings ...
}

我正在尝试在 Pester 中为该函数编写测试。我想创建一个虚拟的 $Website 对象传递给被测函数。问题是该类型没有构造函数。如果没有构造函数Microsoft.Web.Administration.Site,如何在 PowerShell 中创建该类型的对象?Microsoft.Web.Administration.Site

我可以通过 创建一个,IISServerManager.Sites.CreateElement()但我想避免依赖于使用真实的IISServerManager。或者,我可以去掉函数参数 的类型强制转换$Website,这样测试代码就可以传入一个哈希表而不是 Microsoft.Web.Administration.Site 对象。不过,我更倾向于保留类型强制转换,这样脚本的未来维护者就能清楚地知道对象的类型$Website。

有没有办法解决缺少构造函数的问题,而不使用实数IISServerManager或删除类型强制?

powershell
  • 1 个回答
  • 92 Views
Martin Hope
Stan
Asked: 2025-04-26 04:22:45 +0800 CST

正则表达式组名称值包含 2 个以上的单词

  • 6

这段代码运行良好

$pop = New-Object -ComObject wscript.shell
$string = "John Adams, Age: 204, Email: [email protected]"
# Regular expression pattern with named groups
$regex = '(?<Name>\w+\s\w+),\sAge:\s(?<Age>\d+),\sEmail:\s(?<Email>[^\s]+)'
# Apply the regex match
if ($string -match $regex) {
    # Access the groups using automatic variable $matches
    $name = $matches['Name']
    $age = $matches['Age']
    $email = $matches['Email']
    $pop.popup("Name: $name`nAge: $age`nEmail: $email",5,"Success",4096)
} else {
    $pop.popup("No Matches found.",4,"Oh Oh",4096)
}
Exit

但是如果我将字符串改为以 John Quincey Adams 开头,名称组只会返回 Quincey Adams。我知道可以添加一个额外的 \w+\s,但是有没有办法以通用的方式将任意数量的单词名称捕获到组中?

powershell
  • 1 个回答
  • 33 Views
Martin Hope
Maarten ten Velden
Asked: 2025-04-22 22:43:41 +0800 CST

在批处理文件中保留引号 %*

  • 8

我想%*从批处理脚本转发到 Powershell 脚本,这已经可以正常工作了。唯一的问题是我无法干净地转发带有空格的参数。

示例.bat..

@echo off

set cwd=%~dp0
set argv=%*
powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%cwd%Example.ps1' %argv%"

示例.ps1..

Param(
  $Message
)
If (!$Message)
{
  $Message = "Hello!!!"
}
Write-Host $Message

我可以做得./Example.bat Oh很好,打印出来Oh。但是,./Example.bat "Oh no"也只能打印出来Oh。./Example "'Oh no'"虽然可以工作,但并不干净,因为脚本的使用不再相同,这意味着对它的任何使用都会变得紧密耦合,而这是我不想要的。

powershell
  • 4 个回答
  • 109 Views
Martin Hope
Ralf_Reddings
Asked: 2025-04-22 03:33:57 +0800 CST

“using:” 和其他方法无法与 start-threadJob 一起使用,将对象加载到作业会话中

  • 7

运行以下命令将返回错误:

$job=Start-ThreadJob -name maya6 -InitializationScript {. $using:profile} -ScriptBlock {ichild}   #this is an alias defined in the profile

错误:

InvalidOperation: A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or InlineScript in the script workflow. When it is used with Invoke-Command, the Using variable is valid only if the script block is invoked on a remote computer.
ichild: The term 'ichild' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

我也尝试过:

$job=start-threadJob {. $args ; ichild} -ArgumentList $profile      #ichild is an alias defined in my profile

当我使用receive-job $job它时,我的提示冻结了,并且我不断收到以下错误:

Oops, something went wrong.  
Please report this bug with ALL the details below, including both the 'Environment' and 'Exception' sections.  
Please report on GitHub: https://github.com/PowerShell/PSReadLine/issues/new?template=Bug_Report.yaml  
Thank you!  
  
### Environment  
PSReadLine: 2.3.4  
PowerShell: 7.4.6  
OS: Microsoft Windows 10.0.26100  
BufferWidth: 170  
BufferHeight: 21  
  
Last 49 Keys:

我以为using是专门针对这个命令行程序的……

我在 pwsh7.4

powershell
  • 1 个回答
  • 44 Views
Martin Hope
Lusiiky
Asked: 2025-04-20 07:36:16 +0800 CST

如何在启动过程之后重新聚焦 Powershell 脚本?

  • 6

我有一个 Pwsh 脚本,其中的菜单可以执行几种不同的操作来帮助我完成日常工作。

对于其中一项操作,我使用 Start-Process 启动一个进程,只不过它聚焦于启动的窗口,但为了方便起见,我希望在启动后再次聚焦脚本而不是启动的进程。

我不想使用“PassThru”或“NoNewWindow”参数,因为我不想启动的进程在脚本中自行启动,也不想使用最小化的“WindowStyle”,因为无论如何这都会聚焦于启动的进程,也不想使用隐藏,因为我仍然需要在某处看到进程窗口。

我尝试过这种方法,似乎效果最好:

Start-Process -FilePath "MyProcessPath"

Start-Sleep -Seconds 1

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinAp {
 [DllImport("user32.dll")]
 [return: MarshalAs(UnmanagedType.Bool)]
 public static extern bool SetForegroundWindow(IntPtr hWnd);

 [DllImport("user32.dll")]
 [return: MarshalAs(UnmanagedType.Bool)]
 public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}
"@

$p = Get-Process | Where-Object { $_.MainWindowTitle -like "*ScriptTitle*" -and $_.ProcessName -eq "powershell" }

$h = $p.MainWindowHandle
[void] [WinAp]::SetForegroundWindow($h)
[void] [WinAp]::ShowWindow($h, 1)

但不幸的是,它不起作用。它似乎对窗口做了一些操作,因为它在任务栏中闪烁,但并没有获得焦点。似乎虽然脚本是以管理员身份运行的,但它无法像管理员窗口那样获得焦点?

但是,对于脚本的另一部分,我这样做了:

$tempPath = [System.IO.Path]::GetTempFileName().Replace(".tmp", ".vbs")
$code = @'
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.AppActivate "App.exe"
WScript.Sleep 250
WshShell.SendKeys "{ENTER}"
'@

$code | Out-File $tempPath -Encoding ASCII
Start-Process "wscript.exe" $tempPath -Wait
Remove-Item $tempPath

它运行正常……它聚焦窗口,然后按下所需的键(尽管这部分在我目前的问题中不是必需的)。我试过我的脚本,但是……什么也没做。尤其是应用程序是用脚本启动的,所以我想管理员身份也能启动吧?所以我不明白为什么它有效,但脚本本身却不行。

谢谢你!

powershell
  • 3 个回答
  • 113 Views
Martin Hope
Goulven
Asked: 2025-04-19 22:26:06 +0800 CST

Powershell 提示,错误时出现红色尾随字符

  • 7


我正在尝试在中创建自己的 Powershell 提示符$profile。

目前,我有以下内容:

$ESC = [char]27
$RESET = "$ESC[0m"
$pwd = $executionContext.SessionState.Path.CurrentLocation

function prompt {
  $fontColor = "2;192;192;192m"
  $backColor = "2;64;96;128m"
  $shdwColor = "2;32;48;64m"

  $main   = "$RESET$ESC[38;$fontColor$ESC[48;$backColor"
  $shadow = "$RESET$ESC[38;$backColor$ESC[48;$shdwColor"
  $end    = "$RESET$ESC[38;$shdwColor"

  #      "$main $pwd  $shadow $end ";
  #      "$main $pwd  $shadow $end$RESET ";
  #      "$main $pwd  $shadow $end$ESC[0m ";
  #      "$main $pwd  $shadow $end$ESC[0 ";
  #      "$main $pwd  $shadow $end $RESET";
  #      "$main $pwd  $shadow $end $ESC[0m";
  return "$main $pwd  $shadow $end $ESC[0";
}

渲染结果如下:
Powershell 配置文件如下:C:\Windows\System32 / /

当我输入ls或dir(例如)时,一切正常。

但是,当我键入一个字符串时,我的尾随零(从$ESC[0)显示为红色,而当我关闭字符串时,零的颜色变为白色。
Powershell 提示符出现“0”

$RESET当我放置或$ESC[0m代替$ESC[0(但用“m”代替“0”)时也会出现这种情况,而当我删除它们时,它会显示为红色......
与上图相同,但以  作为尾随字符

我们还可以看到,在默认的 Powershell 提示符中,当我们打开一个字符串时,“>”会变成红色:
字符串打开时默认 Powershell 提示为红色“>”

有人在制作提示时遇到过同样的问题吗?如果是,您是如何去除这种颜色的,或者您是如何适应的?

谢谢 !

powershell
  • 2 个回答
  • 62 Views
Martin Hope
marion
Asked: 2025-04-19 20:32:55 +0800 CST

如何修复 Powershell 按钮选择问题?

  • 7

我使用 ChatGPT 生成了代码,以便了解如何自行操作,而且基本上可以正常工作。该脚本用于检查我的电视和电影文件夹中是否存在缺失的文件(folder.jpg、theme.mp3 等),以便 Plex 更好地工作,并显示哪些文件缺失以及缺失的数量。

它在电影文件夹上运行得很好,但我(AI 也不能)想出如何修复它来单击电视或电视结束按钮并让它搜索这些文件夹。

我最好的猜测是第 167 行的 $pathMap 变量是关键,并且它没有正确更新此部分 - $global:fixedPath = $pathMap

有人可以纠正它并向我解释如何解决这个问题吗?

Windows 10 22H2 和 Powershell PSVersion 5.1.19041.5737

    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    
    # Create form
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "Marion's Plex checker"
    $form.Size = New-Object System.Drawing.Size(700, 700)
    $form.StartPosition = "CenterScreen"
    
    # Fixed folder path
    $fixedPath = "D:\ServerFolders\Videos\02 - Movies"
    
    # Path label
    $label = New-Object System.Windows.Forms.Label
    $label.Text = "Checking subfolders in: $fixedPath"
    $label.Location = New-Object System.Drawing.Point(120, 20)
    $label.Size = New-Object System.Drawing.Size(550, 20)
    $form.Controls.Add($label)
    
    # Summary label
    $summaryLabel = New-Object System.Windows.Forms.Label
    $summaryLabel.Text = ""
    $summaryLabel.Location = New-Object System.Drawing.Point(120, 45)
    $summaryLabel.Size = New-Object System.Drawing.Size(550, 20)
    $form.Controls.Add($summaryLabel)
    
    # Output box
    $logBox = New-Object System.Windows.Forms.TextBox
    $logBox.Multiline = $true
    $logBox.ScrollBars = "Vertical"
    $logBox.Location = New-Object System.Drawing.Point(120, 75)
    $logBox.Size = New-Object System.Drawing.Size(550, 350)
    $logBox.Anchor = "Top,Bottom,Left,Right"
    $logBox.ReadOnly = $true
    $form.Controls.Add($logBox)
    
    # Search file buttons (on the left)
    $fileTypes = @("theme.mp3", "folder.jpg", "background.jpg", "poster.jpg")
    $fileButtons = @{}
    $yPos = 20
    $global:selectedFile = "theme.mp3"
    
    foreach ($file in $fileTypes) {
        $btn = New-Object System.Windows.Forms.Button
        $btn.Text = $file
        $btn.Tag = $file
        $btn.Location = New-Object System.Drawing.Point(10, $yPos)
        $btn.Size = New-Object System.Drawing.Size(100, 30)
        $form.Controls.Add($btn)
        $fileButtons[$file] = $btn
        $yPos += 40
    
        $btn.Add_Click({
            $global:selectedFile = $this.Tag
    
            # Reset styles
            foreach ($b in $fileButtons.Values) {
                $b.UseVisualStyleBackColor = $true
            }
    
            # Highlight selected
            # Reset styles
            foreach ($b in $fileButtons.Values) {
                $b.UseVisualStyleBackColor = $true
                $b.BackColor = [System.Drawing.SystemColors]::Control
            }
    
            # Highlight selected
            $this.UseVisualStyleBackColor = $false
            $this.BackColor = 'LightBlue'
    
            $summaryLabel.Text = "Selected file: $global:selectedFile"
        })
    }
    
    # Scan button
    $scanButton = New-Object System.Windows.Forms.Button
    $scanButton.Text = "Scan"
    $scanButton.Location = New-Object System.Drawing.Point(10, 440)
    $scanButton.Size = New-Object System.Drawing.Size(100, 30)
    $form.Controls.Add($scanButton)
    
    # Create a new button for Movies, positioned to the right of the Scan button
    $moviesButton = New-Object System.Windows.Forms.Button
    $moviesButton.Text = "Movies"
    $moviesButton.Size = New-Object System.Drawing.Size(100, 30)
    $moviesButton.Location = New-Object System.Drawing.Point(120, 440)
    
    # Create a new button for TV, positioned next to the Movies button
    $tvButton = New-Object System.Windows.Forms.Button
    $tvButton.Text = "TV"
    $tvButton.Size = New-Object System.Drawing.Size(100, 30)
    $tvButton.Location = New-Object System.Drawing.Point(230, 440)
    
    # Create a new button for TV Ended, positioned next to the TV button
    $tvEndedButton = New-Object System.Windows.Forms.Button
    $tvEndedButton.Text = "TV Ended"
    $tvEndedButton.Size = New-Object System.Drawing.Size(100, 30)
    $tvEndedButton.Location = New-Object System.Drawing.Point(340, 440)  # Right of the TV button
    $tvEndedButton.Add_Click({
        Start-Process "D:\ServerFolders\Videos\TV (Ended)"  # Link to the TV Ended path
    })
    $form.Controls.Add($tvEndedButton)
    
    # Path variables for Movies, TV, and TV Ended
    $pathMap = @{
        "Movies"     = "D:\ServerFolders\Videos\02 - Movies"
        "TV Current" = "D:\ServerFolders\Videos\01 - TV"
        "TV Ended"   = "D:\ServerFolders\Videos\TV (Ended)"
    }
    
    # Default path for Movies
    $global:fixedPath = $pathMap["Movies"]
    $pathLabel.Text = "Scanning path: $global:fixedPath"
    
    # Add click event for Movies button
    $moviesButton.Add_Click({
        $global:fixedPath = $pathMap["Movies"]
        $pathLabel.Text = "Scanning path: $global:fixedPath"
        # Change button colors to indicate active path
        $moviesButton.BackColor = 'LightGreen'
        $tvButton.BackColor = [System.Drawing.SystemColors]::Control
        $tvEndedButton.BackColor = [System.Drawing.SystemColors]::Control
        # Start scanning the Movies path
        Write-Host "Scanning Movies path: $global:fixedPath"
        Scan-Folder -path $global:fixedPath
    })
    
    # Add click event for TV button
    $tvButton.Add_Click({
        $global:fixedPath = $pathMap["TV Current"]
        $pathLabel.Text = "Scanning path: $global:fixedPath"
        # Change button colors to indicate active path
        $tvButton.BackColor = 'LightGreen'
        $moviesButton.BackColor = [System.Drawing.SystemColors]::Control
        $tvEndedButton.BackColor = [System.Drawing.SystemColors]::Control
        # Start scanning the TV Current path
        Write-Host "Scanning TV path: $global:fixedPath"
        Scan-Folder -path $global:fixedPath
    })
    
    # Add click event for TV Ended button
    $tvEndedButton.Add_Click({
        $global:fixedPath = $pathMap["TV Ended"]
        $pathLabel.Text = "Scanning path: $global:fixedPath"
        # Change button colors to indicate active path
        $tvEndedButton.BackColor = 'LightGreen'
        $moviesButton.BackColor = [System.Drawing.SystemColors]::Control
        $tvButton.BackColor = [System.Drawing.SystemColors]::Control
        # Start scanning the TV Ended path
        Write-Host "Scanning TV Ended path: $global:fixedPath"
        Scan-Folder -path $global:fixedPath
    })
    
    # Function to scan the folder
    function Scan-Folder {
        param(
            [string]$path
        )
        Write-Host "Scanning folder: $path"
        # Insert the actual folder scanning logic here
    }
    
    
    # Path variables for Movies, TV, and TV Ended
    $pathMap = @{
        "Movies"     = "D:\ServerFolders\Videos\02 - Movies"
        "TV Current" = "D:\ServerFolders\Videos\01 - TV"
        "TV Ended"   = "D:\ServerFolders\Videos\TV (Ended)"
    }
    
    # Default path for Movies
    $global:fixedPath = $pathMap["Movies"]
    
    # Add click event for Movies button
    $moviesButton.Add_Click({
        $global:fixedPath = $pathMap["Movies"]
        $pathLabel.Text = "Scanning path: $global:fixedPath"
        # Change button colors to indicate active path
        $moviesButton.BackColor = 'LightGreen'
        $tvButton.BackColor = [System.Drawing.SystemColors]::Control
        $tvEndedButton.BackColor = [System.Drawing.SystemColors]::Control
        # Trigger the scanning logic
        Scan-Folder -path $global:fixedPath
    })
    
    # Add click event for TV button
    $tvButton.Add_Click({
        $global:fixedPath = $pathMap["TV Current"]
        $pathLabel.Text = "Scanning path: $global:fixedPath"
        # Change button colors to indicate active path
        $tvButton.BackColor = 'LightGreen'
        $moviesButton.BackColor = [System.Drawing.SystemColors]::Control
        $tvEndedButton.BackColor = [System.Drawing.SystemColors]::Control
        # Trigger the scanning logic
        Scan-Folder -path $global:fixedPath
    })
    
    # Add click event for TV Ended button
    $tvEndedButton.Add_Click({
        $global:fixedPath = $pathMap["TV Ended"]
        $pathLabel.Text = "Scanning path: $global:fixedPath"
        # Change button colors to indicate active path
        $tvEndedButton.BackColor = 'LightGreen'
        $moviesButton.BackColor = [System.Drawing.SystemColors]::Control
        $tvButton.BackColor = [System.Drawing.SystemColors]::Control
        # Trigger the scanning logic
        Scan-Folder -path $global:fixedPath
    })
    
    # Function to scan the folder
    function Scan-Folder {
        param(
            [string]$path
        )
        Write-Host "Scanning folder: $path"
        # Insert the actual scanning logic here to process the folder
    }
    
      # Right of the Movies button
    $tvButton.Add_Click({
        Start-Process "D:\ServerFolders\Videos\01 - TV"  # Link to the TV path
    })
    $form.Controls.Add($tvButton)
      # Right of the Scan button
    $moviesButton.Add_Click({
        Start-Process "D:\ServerFolders\Videos\02 - Movies"  # Link to the Movies path
    })
    $form.Controls.Add($moviesButton)
    
    
    # Globals
    $global:missingItems = @()
    
    function Run-Scan {
        $logBox.Clear()
        $summaryLabel.Text = ""
        $log = @()
        $logPath = Join-Path $fixedPath "missing_${global:selectedFile}_log.txt"
        $csvPath = Join-Path $fixedPath "missing_${global:selectedFile}_report.csv"
        $global:missingItems = @()
    
        if (-not (Test-Path $fixedPath)) {
            [System.Windows.Forms.MessageBox]::Show("Invalid folder path.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
            return
        }
    
        $folders = Get-ChildItem -Path $fixedPath -Directory
    
        foreach ($folder in $folders) {
            $targetFile = Join-Path $folder.FullName $global:selectedFile
            if (-not (Test-Path -LiteralPath $targetFile)) {
                $global:missingItems += $folder
                $logLine = "$($folder.Name)"
                $logBox.AppendText($logLine + "`r`n")
                $log += $logLine
            }
        }
    
        if ($global:missingItems.Count -eq 0) {
            $summaryLabel.Text = "All folders have $($global:selectedFile)."
        } else {
            $summaryLabel.Text = "Missing $($global:selectedFile) from [$($global:missingItems.Count)] folders."
        }
    
        $log | Out-File -FilePath $logPath -Encoding UTF8
    
        $logBox.AppendText("`r`nLog saved to: $logPath`r`n")
        $exportButton.Enabled = $global:missingItems.Count -gt 0
    }
    
    $scanButton.Add_Click({ Run-Scan })
    
    
    # Export to CSV button
    $exportButton = New-Object System.Windows.Forms.Button
    $exportButton.Text = "Export to CSV"
    $exportButton.Location = New-Object System.Drawing.Point(10, 400)
    $exportButton.Size = New-Object System.Drawing.Size(100, 30)
    $exportButton.Enabled = $false
    $form.Controls.Add($exportButton)
    
    $exportButton.Add_Click({
        $csvPath = Join-Path $fixedPath "missing_$($global:selectedFile)_report.csv"
    
        $csvPath = Join-Path $fixedPath "missing_$($global:selectedFile)_report.csv"
        $headerLines = @(
            "File type: $($global:selectedFile)",
            "Total missing: $($global:missingItems.Count)`r`n"
        )
        $headerLines | Out-File -FilePath $csvPath -Encoding UTF8
    
        $global:missingItems | ForEach-Object {
            [PSCustomObject]@{ FolderName = $_.Name; Path = $_.FullName }
        } | Export-Csv -Path $csvPath -Append -NoTypeInformation -Encoding UTF8
    
        $logBox.AppendText("CSV exported to: $csvPath`r`n")
    
    })
    
    
    $form.Topmost = $true
    $form.Add_Shown({ $form.Activate() })
    [void]$form.ShowDialog()

powershell
  • 1 个回答
  • 69 Views
Martin Hope
mr_evans2u
Asked: 2025-04-16 22:24:32 +0800 CST

PowerShell 比较但排除 .txt 文件

  • 6

我只想验证文件夹 1 中的文件是否也位于文件夹 2 中。我只需要验证文件名。出于测试目的,我知道它们是相同的文件,但我无法得到相同的结果。此外,我需要排除文件夹 1 中的一个 *.txt 文件,我之前也从未成功过,甚至在我的两个示例中都没有包含它。我知道这应该很简单,但我一直很纠结。如果这很重要,我正在测试的 zip 文件名是 N324RA_TEST__20240423221326.zip 和 N335RT_TEST_20250410020632.zip。这些文件肯定在文件夹 1 中,我需要验证它们是否也在文件夹 2 中。如果其中一个或两个不在文件夹 2 中,我需要知道

我尝试过:


$Temp = "C:\MaxTemp\"
$Temp2 = "C:\MaxTemp2\"

$files1 = Get-ChildItem  -Path $Temp -Recurse | Where-Object { ! $_.PSIsContainer }
$files2 = Get-ChildItem  -Path $Temp2 -Recurse | Where-Object { ! $_.PSIsContainer } 
write-host "$files1"
write-host "$files2"

if ($fiiles1 -eq $files2)
{write-host "same"
}
else
{write-host "not same"}

这导致文件不一样。我也试过了,但不管怎样,它找到的文件都是一样的。


$Temp = "C:\MaxTemp\"
$Temp2 = "C:\MaxTemp2\"

$files1 = Get-ChildItem -Path $Temp -Recurse | Where-Object { ! $_.PSIsContainer }
$files2 = Get-ChildItem -Path $Temp2 -Recurse | Where-Object { ! $_.PSIsContainer }

if ($comparison) {
    Write-Host "Differences found:"
    $comparison | ForEach-Object {
        if ($_.SideIndicator -eq "<=") {
            Write-Host "Only in $($Temp): $($_.Name)"
        } 

        }
    } 
  else{ ($_.SideIndicator -eq "==") 
            Write-Host "No differences found. Both folders contain the same files."
        }  
powershell
  • 2 个回答
  • 33 Views
Martin Hope
RustyAndroid
Asked: 2025-04-16 08:32:23 +0800 CST

PowerShell - 查找系统时出现错误消息

  • 5

我编写了一个用于重启网络上计算机的脚本。它运行良好,唯一的问题是主机中会弹出错误消息。该脚本会从一个txt文件($Computers)中提取系统名称列表。我用一个我能访问的系统测试了该脚本,并在列表中添加了单词“wrench”,以模拟一个不在网络上的系统。测试脚本时,它在查找“wrench”时抛出了一条错误消息。以下是我目前脚本实际重启部分的内容:

#Actual restart portion (for privacy reasons, real file path replaced with "file-path")
#Starts by moving most recent log to archive folder
Get-ChildItem -Path "\\file-path\Computer Restarts\Logs" -Recurse -File | Move-Item -Destination "\\file-path\Computer Restarts\Logs\Archive" -Force

     #Determine script location, create new script, get current time and date
     $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
     $Log = New-Item "\\file-path\Computer Restarts\Logs\$(Get-Date -f yyyy-MM-dd_hh-mm-ss) Restarts.txt" -ItemType File -Force
     $Date = Get-Date -Format "dd-MMM-yyyy hh:mm:ss"
     $Now = [datetime]::Now

     Clear-Host
     Write-Host `n `n `n
     Write-Host "Rebooting all computers and verifying reboot status..." `n `n
     Write-Host "Please standby, process may take up to 30 minutes..." `n `n

     Restart-Computer -ComputerName $Computers -Wait -For PowerShell -Delay 2 -Force -Timeout 1800 # Restarts all listed systems at once

     "----------------------------------Script executed on $Date----------------------------------" + "`r`n" | Out-File $Log -Append #First thing added to new log

     foreach($Computer in $Computers) #Checks each server to see if it has rebooted. Waits for confirmation before moving to next computer, skips computer if unresponsive after short time.
     {
         $LastBoot = (Get-CimInstance Win32_OperatingSystem -ComputerName $Computer -EA 0).LastBootUpTime
         $PingRequest = Test-Connection -ComputerName $Computer -Count 1 -Quiet

         if(($PingRequest -eq $true) -and ($LastBoot -gt $Now))
         {
             Add-Content -Path $Log -Value "$Computer`: Reboot Successful."
         }
         elseif ($PingRequest -eq $false)
         {
             Add-Content -Path $Log -Value "$Computer`: Computer not detected, please confirm."
         }
         else
         {
             Add-Content -Path $Log -Value "$Computer`: Restart not detected, please restart computer manually. Last detected boot up time is $LastBoot"
         }
     }

“Wrench”不会破坏脚本,据我所知,但我更希望脚本只是悄悄地处理它找不到的系统,只需将其附加到日志中,而不是在主机中抛出错误消息。

powershell
  • 1 个回答
  • 33 Views
Martin Hope
9072997
Asked: 2025-04-14 22:19:21 +0800 CST

PowerShell 中 ValidateScript 的生命周期是多长?

  • 8

PowerShell 支持变量验证脚本。这最常用于验证函数参数,但也可以应用于任何变量。每次变量值发生变化时,这些验证脚本都会运行。

# create a variable with a validation script
[ValidateScript({
    if (-not ($_.Length -in @(8, 16, 24))) {
        Write-Host 'Validate Failed'
        throw "Value '$_' has invalid length: $($_.Length)"
    } else {
        Write-Host 'Validate Success'
    }
    $true
})][System.String]$MyValidatedArg = "a" * 8 # prints "Validate Success"

# Each one of these will trigger the validation script
Write-Host "Several valid assignments..."
$MyValidatedArg = "b" * 8 # prints "Validate Success"
$MyValidatedArg = "b" * 8 # prints "Validate Success"
$MyValidatedArg = "b" * 16 # prints "Validate Success"
$MyValidatedArg = "b" * 24 # prints "Validate Success"

如果我给变量分配一个无效值,它会引发异常

$MyValidatedArg = "foo" # throws an exception

奇怪的是,如果我在赋值过程中重新指定类型约束,就可以绕过验证脚本。我知道“别这么做”是个选择,但我的问题重点是:为什么这样做有效?

[System.String]$MyValidatedArg = "123456789" # works even though this value is invalid

起初我以为这只是一个变量遮蔽的问题。比如,我可能通过再次指定类型约束来创建第二个变量或对象之类的东西。我尝试捕获对该变量的引用,看看该引用是否会保留验证脚本。结果并没有,但我对 PowerShell 的内部机制不太熟悉,无法判断这是否是一个有效的测试。

# create a reference and assign through the reference
Write-Host "Assigning through reference..."
$refToParameter = [ref] $MyValidatedArg
$refToParameter.Value = "c" * 24 # prints "Validate Success"
Write-Host " Read via variable: $MyValidatedArg"
Write-Host " Read via reference: $($refToParameter.Value)"

# the reference and the variable are linked
# Assignments to either trigger the validation script
Write-Host "Assigning through normal variable again..."
$MyValidatedArg = "d" * 24 # prints "Validate Success"
Write-Host " Read via variable: $MyValidatedArg"
Write-Host " Read via reference: $($refToParameter.Value)"

# This works, which is odd
Write-Host "Assigning with [System.String]..."
[System.String]$MyValidatedArg = "123456789" # invalid, nothing printed
Write-Host " No exceptions yet!"

# I thought this was some sort of variable shadowing thing, but the reference shows the new value too
Write-Host "The link between the variable and the reference is still there..."
$MyValidatedArg = "e" * 8 # valid, nothing printed
Write-Host " Read via variable: $MyValidatedArg"
Write-Host " Read via reference: $($refToParameter.Value)"

# and now we appear to have killed the validation script
Write-Host "Regular invalid assignment..."
$MyValidatedArg = "123456789" # invalid, nothing printed
Write-Host " It works now for some reason"
powershell
  • 1 个回答
  • 53 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve