[玩转系统] 解决 PowerShell 内存挑战
作者:精品下载站 日期:2024-12-14 08:01:46 浏览:18 分类:玩电脑
解决 PowerShell 内存挑战
我希望您能尝试一下有关报告内存使用情况的 Iron Scripter PowerShell 挑战。基本挑战是找到特定进程或服务正在使用的工作集内存的总百分比。这是我的处理方法,我通常免责声明,我的解决方案不是唯一的,也不应该被认为是权威的。尽管如此,我还是希望您能掌握 PowerShell 脚本编写技巧或技术。
使用 Get-CimInstance
我的第一种方法使用 Get-CimInstance,主要是因为它可以从远程计算机获取信息。我将要执行的代码是可以在 PowerShell 提示符下运行的命令。一旦这些命令起作用并产生我想要的结果,我就可以将它们包装到一个函数中。
首先,我需要了解当前正在使用多少内存。
$computername = $env:COMPUTERNAME
$os = Get-CimInstance win32_operatingsystem -Property TotalVisibleMemorySize,FreePhysicalMemory -Computername $computername
$inUseMemory = ($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)*1KB
让我指出将 -Property 参数与 Get-CimInstance 一起使用。这是您可以做的一件小事,可能会带来积极的性能提升。从 CIM 存储库获取信息非常类似于 SQL 查询。最好、最快的查询是您只选择所需属性的查询。因为我只需要两个内存属性,所以这就是我所要求的。根据经验和之前的研究,我还知道这些值以 KB 为单位。将值乘以 1KB 会将值转换为字节。
使用此值,我可以查询特定服务并创建自定义输出,以计算正在使用的总内存中的工作集内存百分比。
Get-CimInstance win32_process -filter "name='sqlservr.exe'" |
Select-Object -Property ProcessID,Name,HandleCount,WorkingSetSize,
@{Name="PctUsedMemory";Expression = {($_.WorkingSetSize/$InUseMemory) * 100}}
将其转变为简单的 PowerShell 函数并不需要太多时间。
但与此同时,我会将这个概念扩展到除系统空闲之外的所有进程。
Get-CimInstance -class win32_process -computername $computername -filter "Name<>'systemidleprocess'" |
Group-Object -property Name |
ForEach-Object {
$stat = $_.Group | Measure-Object -Property WorkingSetSize -sum
$_ | Select-Object -Property Name,Count,@{Name="TotalWS";Expression={$stat.sum}},
@{Name="PctUsedMemory";Expression={[math]::Round(($stat.sum/$InUseMemory)*100,2)}}
} | Sort-Object -property PctUsedMemory -Descending|
Select-Object -first 10 |
Format-Table
此代码还使用我在开始时检索到的 $InUseMemory 值。流程实例根据“名称”属性进行分组。这是因为我可能有 10 个 svchost 进程,并且我想将它们视为一项。
然后使用 ForEach-Object 枚举分组的对象。对于组中的每个项目,我都会测量该组的总工作集大小。
$stat = $_.Group | Measure-Object -Property WorkingSetSize -sum
然后,我使用 Select-Object 创建一个自定义对象来定义新属性。结果通过管道传输到 Sort-Object,以按降序对自定义 PctUsedMemory 属性进行排序。排序后的结果通过管道传输到 Select-Object 以获取前 10 个结果。最后,为了使其在屏幕上美观,我将结果格式化为表格。
如果我要把它变成一个函数,我很可能会创建一个真正的自定义对象,而不是依赖 Select-Object。
$computername = $env:COMPUTERNAME
$os = Get-CimInstance win32_operatingsystem -Property TotalVisibleMemorySize,FreePhysicalMemory -Computername $computername
$inUseMemory = ($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)* 1KB
$grouped = Get-CimInstance win32_process -computername $computername -filter "Name <>'system idle process'" |
Group-Object -property Name
$results = ForEach ($item in $Grouped) {
$stat = $item.Group | Measure-Object -Property WorkingSetSize -Sum
[pscustomobject]@{
PSTypeName = "ProcessWSPercent"
Name = $item.Name
Count = $item.count
TotalWS = $stat.sum
PctUsedMemory = [math]::Round(($stat.sum / $InUseMemory) * 100, 2)
}
}
$results | Sort-Object -property PctUsedMemory -Descending |
Select-Object -first 10
我认为这种方法在脚本文件中更容易阅读。如果我愿意,我可以创建一个自定义 format.ps1xml 文件来格式化结果。也许以MB而不是字节为单位显示TotalWS,这就是我现在所拥有的。
使用获取进程
这是使用 Get-Process 的变体。在此版本中,我将从所有进程中获取总工作集值。
$ps = Get-Process
$totalWS = ($ps | Measure-Object -Property WS -Sum).sum
现在我可以过滤、选择、排序并选择我想查看的内容。
$ps | Where-Object {$_.name -notmatch "^(system|idle)$"} |
Select-Object -property Name,WS,@{Name="PctTotalWS";Expression = {($_.ws/$totalWS)*100}} |
Sort-Object -Property PctTotalWS -Descending |
Select-Object -first 10
此变体显示每个过程的结果。我可以按照与之前类似的方式对它们进行分组。
$ps | Where-Object { $_.name -notmatch "^(system|idle)$" } |
Group-Object -Property name |
ForEach-Object {
$wsSum = ($_.group | Measure-Object -Property WS -Sum).sum
[PSCustomObject]@{
Name = $_.Name
Count = $_.count
TotalWS = $wsSum
PctTotalWS = [math]::round(($wsSum / $totalWS) * 100, 4)
}
} | Sort-Object -Property PctTotalWS -Descending | Select-Object -First 5
同样,将其转变为易于使用的 PowerShell 函数并不需要太多时间。
使用性能计数器
我解决这个问题的最后一种方法是使用性能计数器。我将使用可能有多个实例的单个进程。
$name = "firefox"
$Counters = (Get-Counter "\process(firefox*)\Working Set").CounterSamples
$total = ($counters | Measure-Object -property CookedValue -sum).Sum
$committed = (Get-Counter "\memory\committed bytes").Countersamples[0].CookedValue
$pct = ($total/$committed)*100
您会注意到,我使用索引 [0] 来获取提交的字节值,即使您运行 Get-Counter 命令您也只会看到一个结果。 Get-Counter 有一个小怪癖,它返回一个带有空第二个值的数组。使用这些值,我可以创建一个结果对象。
[pscustomobject]@{
ProcessName = $name
ProcessCount = $counters.count
TotalWS = [math]::round($total / 1mb, 4)
PctCommitted = [math]::round($pct, 4)
}
我将把这个概念扩展到所有流程,再次对类似的流程进行分组。
[pscustomobject]@{
ProcessName = $name
ProcessCount = $counters.count
TotalWS = [math]::round($total / 1mb, 4)
PctCommitted = [math]::round($pct, 4)
}
我的代码使用正则表达式来过滤掉选择的性能计数器结果。其余代码应该看起来很熟悉。
$data = foreach ($item in $grouped) {
$total = ($item.group | Measure-Object -Property CookedValue -Sum).Sum
$pct = ($total / $committed) * 100
[pscustomobject]@{
ProcessName = $item.Name
ProcessCount = $item.count
TotalWS = [math]::round($total / 1mb, 4)
PctCommitted = [math]::round($pct, 4)
}
}
$data | Sort-Object TotalWS -Descending | Select-Object -first 10
此代码应在 Windows 机器人 Windows PowerShell 和 PowerShell 7.1 下运行。
服务
最后,让我们看看如何从服务角度解决这个问题。正在运行的服务是一个正在运行的进程,因此我应该能够使用我已经向您展示的大部分代码。我将重新运行代码以获取 $InUseMemory 值。
$computername = $env:COMPUTERNAME
$os = Get-CimInstance win32_operatingsystem -Property TotalVisibleMemorySize,FreePhysicalMemory -Computername $computername
$inUseMemory = ($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)* 1KB
我将使用 Get-CimInstance 查询 Win32_Service 类,因为它将包含关联的进程 ID。因此,对于每个服务,我可以获得相应的流程并构建自定义对象。
Get-CimInstance -classname win32_service -Filter "state = 'running'" -Property Name, ProcessID -ComputerName $computername |
ForEach-Object -Begin {
#define a hashtable of parameters to splat to Get-CimInstance in the process block
$splat = @{
ClassName = "Win32_process"
filter = ""
Property = "Name", "ProcessID", "WorkingSetSize"
Computername = $Computername
}
} -Process {
#update the filter
$splat.filter = "processid=$($_.processid)"
$proc = Get-CimInstance @splat
[pscustomobject]@{
PSTypeName = "svcMemoryDetail"
ServiceName = $_.Name
ProcessName = $proc.Name
ProcessID = $proc.ProcessId
TotalWS = $proc.WorkingSetSize
PctUsedMemory = [math]::Round(($proc.WorkingSetSize / $inUseMemory) * 100, 4)
}
} | Sort-Object PctUsedMemory -Descending | Select-Object -First 10 | Format-Table
如果我要继续并围绕此创建一个函数,我还会创建一个自定义 format.ps1xml 文件来呈现一个漂亮的表格。
包起来
如果您关注我一段时间,您应该会认识到熟悉的工作流程。
- 编写在提示符下交互式运行的代码。
- 创建一个包含将对象写入管道的代码的函数。
- 添加自定义类型和格式更新,以便轻松处理命令结果。
如果您在控制台代码中使用变量,就像我对 $Computername 所做的那样,那么将它们用作函数参数并不需要太多努力。
诚然,这篇文章涉及很多内容,所以如果您有疑问或需要一些澄清,请不要害羞。很可能其他人也这样做。否则,我希望您自己尝试一些代码,看看它是如何工作的。我还希望您尝试一下 Iron Scripter 挑战。所有级别都有测试,并且没有截止日期。
祝你好运。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag