[玩转系统] 解决 PowerShell 转换挑战
作者:精品下载站 日期:2024-12-14 08:01:16 浏览:14 分类:玩电脑
解决 PowerShell 转换挑战
今天,让我们看看我是如何应对今年第一个 Iron Scripter PowerShell 挑战的。挑战的目标是将对象转换或翻译为 PowerShell 类定义。如果您是这些挑战的新手,那么实现目标的过程比最终结果更有价值。这些挑战旨在成为学习练习。
从单个对象开始
为了定义一个新的对象类,我需要一个对象作为我的模板。
$obj=Get-CimInstancewin32_operatingsystem-ComputerNamelocalhost
在此特定示例中,我还可以使用 Get-CimClass 列出属性名称。但由于我希望能够从任何类型的对象定义一个类,所以我将忽略这个替代方案。
相反,我将依赖隐藏的 PowerShell 功能。 PowerShell 易于使用的原因之一是它抽象或隐藏了许多 .NET 开发人员的内容。这很棒,因为这意味着您不必成为开发人员即可使用 PowerShell。然而,随着您获得经验,您可以剥离其中一些抽象概念。这就是我要做的。我将获得一个通用的psobject属性。
这是对象的更通用的表示。让我们更深入地探讨一下。
我可以看到属性名称及其类型,这将有助于定义我的类。 PowerShell 类定义如下所示:
class myClass {
[typename]$PropertyName
...
}
我可以使用 -f 运算符定义属性线。
$prop=$obj.PSobject.properties|Select-Object-First1
"[{0}]`"-f$prop.TypeNameOfValue,$prop.name
{0} 和 {1} 条目是占位符,它们是使用 -f 运算符右侧的值填充的。我还转义了 $,所以它是按字面意思处理的。创建的字符串为 [System.Boolean]$PSShowComputerName
考虑到这一点,我可以生成该对象的完整类版本。
$obj.psobject.properties|ForEach-Object-Begin{
$class=@"
classmyOS{
#properties
"@
}-Process{$class+="[{0}]``n"-f$_.TypeNameOfValue,$_.name}-End{$class+="}"}
这就是我最终得到的结果。
class myOS {
properties
[System.Boolean]$PSShowComputerName
[string]$Caption
[string]$Description
[CimInstance#DateTime]$InstallDate
[string]$Name
[string]$Status
[string]$CreationClassName
[string]$CSCreationClassName
[string]$CSName
[int16]$CurrentTimeZone
[bool]$Distributed
[uint64]$FreePhysicalMemory
[uint64]$FreeSpaceInPagingFiles
[uint64]$FreeVirtualMemory
[CimInstance#DateTime]$LastBootUpTime
[CimInstance#DateTime]$LocalDateTime
[uint32]$MaxNumberOfProcesses
[uint64]$MaxProcessMemorySize
[uint32]$NumberOfLicensedUsers
[uint32]$NumberOfProcesses
[uint32]$NumberOfUsers
[uint16]$OSType
[string]$OtherTypeDescription
[uint64]$SizeStoredInPagingFiles
[uint64]$TotalSwapSpaceSize
[uint64]$TotalVirtualMemorySize
[uint64]$TotalVisibleMemorySize
[string]$Version
[string]$BootDevice
[string]$BuildNumber
[string]$BuildType
[string]$CodeSet
[string]$CountryCode
[string]$CSDVersion
[bool]$DataExecutionPrevention_32BitApplications
[bool]$DataExecutionPrevention_Available
[bool]$DataExecutionPrevention_Drivers
[byte]$DataExecutionPrevention_SupportPolicy
[bool]$Debug
[uint32]$EncryptionLevel
[byte]$ForegroundApplicationBoost
[uint32]$LargeSystemCache
[string]$Locale
[string]$Manufacturer
[string[]]$MUILanguages
[uint32]$OperatingSystemSKU
[string]$Organization
[string]$OSArchitecture
[uint32]$OSLanguage
[uint32]$OSProductSuite
[bool]$PAEEnabled
[string]$PlusProductID
[string]$PlusVersionNumber
[bool]$PortableOperatingSystem
[bool]$Primary
[uint32]$ProductType
[string]$RegisteredUser
[string]$SerialNumber
[uint16]$ServicePackMajorVersion
[uint16]$ServicePackMinorVersion
[uint32]$SuiteMask
[string]$SystemDevice
[string]$SystemDirectory
[string]$SystemDrive
[string]$WindowsDirectory
[string]$PSComputerName
[Microsoft.Management.Infrastructure.CimClass]$CimClass
[Microsoft.Management.Infrastructure.Generic.CimKeyedCollection`1[[Microsoft.Management.Infrastructure.CimProperty, Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]]$CimInstanceProperties
[Microsoft.Management.Infrastructure.CimSystemProperties]$CimSystemProperties
}
我可能不需要所有这些属性,我稍后会处理它。但首先让我尝试使用不同类型的物体并完善我的技术。
$properties = "Name","Displayname","MachineName","StartType"
(Get-Service bits).psobject.properties |
Where-Object {$properties -contains $_.name} |
ForEach-Object -Begin {
$class = @"
class mySvc {
#properties
"@
} -Process { $class += "[{0}]``n" -f $_.TypeNameOfValue, $_.name } -End { $class += "}" }
我的结果是:
class mySvc {
properties
[System.String]$Name
[System.String]$DisplayName
[System.String]$MachineName
[System.ServiceProcess.ServiceStartMode]$StartType
}
转换对象到类
现在我已经从提示中获得了工作代码,我可以将其封装在一个函数中并添加功能。
Function Convert-ObjectToClass {
[cmdletbinding()]
[outputType([String])]
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipeline)]
[object]$InputObject,
[Parameter(Mandatory, HelpMessage = "Enter the name of your new class")]
[string]$Name,
[string[]]$Properties,
[string[]]$Exclude
)
Begin {
Write-Verbose "Starting $($myinvocation.MyCommand)"
} #begin
Process {
Write-Verbose "Converting existing type $($InputObject.getType().Fullname)"
#create a list to hold properties
$prop = [system.collections.generic.list[object]]::new()
#define the class here-string
$myclass = @"
# this class is derived from $($InputObject.getType().Fullname)
class $Name {
#properties
"@
#get the required properties
if ($Properties) {
$InputObject.psobject.properties | Where-Object { $Properties -contains $_.name } |
Select-Object -Property Name, TypeNameOfValue |
ForEach-Object {
Write-Verbose "Adding $($_.name)"
$prop.Add($_)
} #foreaach
} #if Properties
else {
Write-Verbose "Adding all properties"
$InputObject.psobject.properties | Select-Object -Property Name, TypeNameOfValue |
ForEach-Object {
Write-Verbose "Adding $($_.name)"
$prop.Add($_)
} #foreach
} #else all
if ($Exclude) {
foreach ($item in $Exclude) {
Write-Verbose "Excluding $item"
#remove properties that are tagged as excluded from the list
[void]$prop.remove($($prop.where({ $_.name -like $item })))
}
}
Write-Verbose "Processing $($prop.count) properties"
foreach ($item in $prop) {
#add the property definition name to the class
#e.g. [string]$Name
$myclass += "[{0}]`${1}`n" -f $item.TypeNameOfValue, $item.name
}
#add placeholder content to the class definition
$myclass += @"
#Methods can be inserted here
<#
[returntype] MethodName(<parameters>) {
code
return value
}
#>
#constructor placeholder
$Name() {
#insert code here
}
} #close class definition
"@
#if running VS Code or the PowerShell ISE, copy the class to the clipboard
#this code could be modified to insert the class into the current document
if ($host.name -match "ISE|Visual Studio Code" ) {
$myClass | Set-Clipboard
$myClass
Write-Host "The class definition has been copied to the Windows clipboard." -ForegroundColor green
}
else {
$myClass
}
} #process
End {
Write-Verbose "Ending $($myinvocation.MyCommand)"
} #end
}
函数名称有争议。我使用的名称实际上是函数将完成的任务的字面表示。但“ObjectToClass”是一个奇怪的名词。更好的名称可能是 ConvertTo-PSClass。还可以使用不同的动词进行论证,例如Out或Export。这些都是不容忽视的设计考虑因素。
我的函数包括 PowerShell 代码来检测它是否在 PowerShell ISE 或 VS Code 中运行,如果是,则将类复制到剪贴板。我有点犹豫是否将其包含在函数中,因为这是与定义类不同的任务,并且 PowerShell 函数应该只做一件事。但是,这段代码没有添加任何管道输出,从我的角度来看,我正在运行该函数来创建一个可以在脚本项目中使用的类定义。
我可以这样使用它:
Get-Ciminstance win32_Operatingsystem | Convert-ObjectToClass -Properties Caption,CSName,Version,InstallDate -Name myOS
类定义远非完美,我希望必须对其进行改进。
this class is derived from Microsoft.Management.Infrastructure.CimInstance
class myOS {
properties
[string]$Caption
[CimInstance#DateTime]$InstallDate
[string]$CSName
[string]$Version
Methods can be inserted here
<# [returntype] MethodName(<parameters>) { code return value } #>
constructor placeholder
myOS() {
#insert code here
}
} #close class definition
例如,InstallDate 需要是 [DateTime] 对象。我还知道我需要重命名一些属性,例如将 $CSName 重命名为 $Computername。但我的职能让我开始了。
既然已经开始了,我不妨给大家介绍一下整个过程。这是我修改后的类定义。
class myOS {
#properties
[string]$Name
[DateTime]$InstallDate
[string]$Computername = $env:COMPUTERNAME
[string]$Version
[datetime]$AuditDate = (Get-Date)
#Methods can be inserted here
hidden [timespan] GetInstallAge() {
$time = New-TimeSpan -Start $this.InstallDate -End (Get-Date)
return $time
}
#constructor placeholder
myOS([string]$Computername) {
$os = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $Computername
$this.name = $os.caption
$this.version = $os.Version
$this.installDate = $os.InstallDate
$this.Computername = $Computername
}
} #close class definition
因为我正在定义自定义对象,所以我还可以定义类型和格式扩展,尽管我现在跳过后者。
Update-TypeData -TypeName myOS -MemberType ScriptProperty -MemberName InstallAge -Value { $this.GetInstallAge() } -Force
我最不需要的就是为用户提供一种使用该类的简单方法。我不想强迫用户必须使用原始类定义。相反,创建您自己的辅助函数。
Function Get-OS {
[cmdletbinding()]
[Outputtype("myOS")]
Param([string[]]$Computername = $env:COMPUTERNAME)
foreach ($computer in $computername) {
New-Object -TypeName myOS -ArgumentList $computer
}
}
我不得不承认,我可能真的会用到这个功能。这绝对不是初学者级别的 PowerShell,所以如果您有疑问,请不要害羞并在评论中提问。
猜你还喜欢
- 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