Yor*_*ubs 5 console powershell
我制作了一个小诊断脚本,并将其保存在我的$profile. 在收集 CPU 名称时,我发现该命令大约需要 4 秒(Get-WmiObject -Class Win32_Processor).Name。所以我想我应该尝试 PowerShell Jobs,虽然我认为它们非常适合长时间的后台作业,但如果您只想快速获取后台的一小段信息,那么初始化时间会很尴尬(例如 2-3每个作业秒),所以我想在脚本的其余部分运行时使用 Start-Process 将值转储到临时文件中。我认为我这样做是正确的,但如果您运行此函数 3 或 4 次,您会注意到 CPU 名称未填充。
\xe2\x80\xa2 使用这样的 Start-Process 是否是最佳选择,或者是否有人有更快的方法来在后台并行启动小作业?我知道有一种 .NET 方法可以做到这一点(但从我所看到的来看,它似乎超级复杂)?
\n\n\xe2\x80\xa2 你知道为什么我的“等待文件创建并在访问它之前非零”经常失败吗?
\n\nfunction sys {\n $System = get-wmiobject -class "Win32_ComputerSystem"\n $Mem = [math]::Ceiling($System.TotalPhysicalMemory / 1024 / 1024 / 1024)\n\n $wmi = gwmi -class Win32_OperatingSystem -computer "."\n $LBTime = $wmi.ConvertToDateTime($wmi.Lastbootuptime)\n [TimeSpan]$uptime = New-TimeSpan $LBTime $(get-date)\n $s = "" ; if ($uptime.Days -ne 1) {$s = "s"}\n $uptime_string = "$($uptime.days) day$s $($uptime.hours) hr $($uptime.minutes) min $($uptime.seconds) sec"\n\n $temp_cpu = "$($env:TEMP)\\ps_temp_cpu.txt"\n $temp_cpu_cores = "$($env:TEMP)\\ps_temp_cpu_cores.txt"\n $temp_cpu_logical = "$($env:TEMP)\\ps_temp_cpu_logical.txt"\n rm -force $temp_cpu -EA silent ; rm -force $temp_cpu_cores -EA silent ; rm -force $temp_cpu_logical -EA silent\n Start-Process -NoNewWindow -FilePath "powershell.exe" -ArgumentList "-NoLogo -NoProfile (Get-WmiObject -Class Win32_Processor).Name > $temp_cpu"\n Start-Process -NoNewWindow -FilePath "powershell.exe" -ArgumentList "-NoLogo -NoProfile (Get-WmiObject -Class Win32_Processor).NumberOfCores > $temp_cpu_cores"\n Start-Process -NoNewWindow -FilePath "powershell.exe" -ArgumentList "-NoLogo -NoProfile (Get-WmiObject -Class Win32_Processor).NumberOfLogicalProcessors > $temp_cpu_logical"\n ""\n "Hostname: $($System.Name)"\n "Domain: $($System.Domain)"\n "PrimaryOwner: $($System.PrimaryOwnerName)"\n "Make/Model: $($System.Manufacturer) ($($System.Model))" # "ComputerModel: $((Get-WmiObject -Class:Win32_ComputerSystem).Model)"\n "SerialNumber: $((Get-WmiObject -Class:Win32_BIOS).SerialNumber)"\n "PowerShell: $($PSVersionTable.PSVersion)"\n "Windows Version: $($PSVersionTable.BuildVersion)"\n "Windows ReleaseId: $((Get-ItemProperty -Path \'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\' -Name \'ReleaseId\').ReleaseId)"\n "Display Card: $((Get-WmiObject -Class:Win32_VideoController).Name)"\n "Display Driver: $((Get-WmiObject -Class:Win32_VideoController).DriverVersion)"\n "Display ModelDesc: $((Get-WmiObject -Class:Win32_VideoController).VideoModeDescription)"\n "Last Boot Time: $([Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem | select \'LastBootUpTime\').LastBootUpTime))" # $(wmic OS get LastBootupTime)\n "Uptime: $uptime_string"\n # ipconfig | sls IPv4\n Get-Netipaddress | where AddressFamily -eq IPv4 | select IPAddress,InterfaceIndex,InterfaceAlias | sort InterfaceIndex\n\n # Get-PSDrive | sort -Descending Free | Format-Table\n # /sf/ask/2600806281/\n # https://www.petri.com/checking-system-drive-free-space-with-wmi-and-powershell\n # https://www.oxfordsbsguy.com/2017/02/08/powershell-how-to-check-for-drives-with-less-than-10gb-of-free-diskspace/\n # Get-Volume | Where-Object {($_.SizeRemaining -lt 10000000000) -and ($_.DriveType -eq \xe2\x80\x9cFIXED\xe2\x80\x9d) -and ($_.FileSystemLabel -ne \xe2\x80\x9cSystem Reserved\xe2\x80\x9d)}\n gwmi win32_logicaldisk | Format-Table DeviceId, VolumeName, @{n="Size(GB)";e={[math]::Round($_.Size/1GB,2)}},@{n="Free(GB)";e={[math]::Round($_.FreeSpace/1GB,2)}}\n\n # Note: -EA silent on Get-Item otherwise get an error\n while (!(Test-Path $temp_cpu)) { while ((Get-Item $temp_cpu -EA silent).length -eq 0kb) { Start-Sleep -Milliseconds 500 } }\n "CPU: $(cat $temp_cpu)"\n while (!(Test-Path $temp_cpu_cores)) { while ((Get-Item $temp_cpu_cores -EA silent).length -eq 0kb) { Start-Sleep -Milliseconds 500 } }\n "CPU Cores: $(cat $temp_cpu_cores)"\n while (!(Test-Path $temp_cpu_logical)) { while ((Get-Item $temp_cpu_logical -EA silent).length -eq 0kb) { Start-Sleep -Milliseconds 500 } }\n "CPU Logical: $(cat $temp_cpu_logical)"\n rm -force $temp_cpu -EA silent ; rm -force $temp_cpu_cores -EA silent ; rm -force $temp_cpu_logical -EA silent\n "Memory: $(Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | Foreach {"{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))}) GB"\n ""\n "Also note the \'Get-ComputerInfo\' Cmdlet (has more info but slower to run)"\n ""\n}\nRun Code Online (Sandbox Code Playgroud)\n
Jaw*_*wad 11
要在 powershell 中后台运行作业,有以下 3 种方法
1. Invoke-Command[3] -scriptblock { script } -asJob -computername localhost
2. Start-Job[2] -scriptblock { script }
3. Start-Process[1] powershell {script}
如果您确实想在后台运行事物,并且每个作业彼此独立,则必须考虑使用第一个或第二个选项,因为它们都不需要将输出写入文件。
Invoke-Command启动与系统的新会话并在新实例中运行作业。
Start-Job在新的 powershell 实例下在后台创建一个新作业,需要更多时间来分配资源并启动进程。就像 start-process 一样,Start-Job 将在单独的 powershell.exe 实例中运行作业。
Start-Process要求您将标准输出重定向到文件[1]。您必须依赖磁盘的性能以及读写速度。您还必须确保不超过一个线程正在读取/写入该进程的输出。
我发现Invoke-Command在运行 100 个并发作业以获取处理器信息时速度最快的建议。此选项确实要求您提供 -ComputerName,然后要求您成为管理员才能与 localhost 启动 winrm 会话。如果您在创建作业时不输出作业信息,则不会占用任何大量时间。
Start-Job 和 Invoke-Command 都需要大约一秒钟的时间来获取处理器信息,并且运行 100 个并发作业来获取相同的信息需要一些开销。
$x = 0..100 | Invoke-Command -computername localhost -scriptblock { script } -asJob
$x | % { $_ | wait-job | out-null }
$output = $x | % { $_ | Receive-Job}
# You can run measure-object, sort-object, etc as well
Run Code Online (Sandbox Code Playgroud)
[1]启动进程
RedirectStandardOutput:指定文件。此 cmdlet 将进程生成的输出发送到您指定的文件。输入路径和文件名。默认情况下,输出显示在控制台中。
[2]开始工作
Start-Job cmdlet 在本地计算机上启动 PowerShell 后台作业。... PowerShell 后台作业运行命令而不与当前会话交互。
[3]调用命令
Invoke-Command cmdlet 在本地或远程计算机上运行命令并返回命令的所有输出,包括错误。...要在后台作业中运行命令,请使用 AsJob 参数
| 归档时间: |
|
| 查看次数: |
15516 次 |
| 最近记录: |