如何在 Powershell 脚本中创建函数?
How to create a function in Powershell script?
如何编写一个函数来避免我的 powershell 脚本的重复代码,它基本上显示了我机器上安装的应用程序列表,这些应用程序来自控制面板中的添加和删除 window。
下面是powershell脚本
堆叠.ps1
Clear-Host
#$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$scriptPath = $PSScriptRoot
$logFilePath= Join-path $scriptPath "TestResults.log"
#If log file exists, then clear its contents
if (Test-Path $logFilePath)
{
clear-content -Path $logFilePath
}
$log = "Date Of Testing: {0} " -f (Get-Date)
$logString = "Process Started."
add-content -Path $logFilePath -Value $log -Force
add-content -Path $logFilePath -Value $logString -Force
add-content -Path $logFilePath -Value "`n" -Force
#Validate ADD/Remove Program list
add-content -Path $logFilePath -Value "`n" -Force
add-content -Path $logFilePath -Value "Add/Remove Programs :" -Force
add-content -Path $logFilePath -Value "`n" -Force
$InstalledPrograms = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
add-content -Path $logFilePath -Value "`n" -Force
foreach ($InstalledProgram in $InstalledPrograms )
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Operational Control")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Publisher: $logp" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force****
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Management Studio")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Publisher: $logp" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("System Analyzer")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Publisher: $logp" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("STeP")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force
}
}
我说的是每个 if 语句下的代码,用于将输出复制到日志文件。我可以用函数替换该代码并在每个 if 语句中调用该函数吗?
好的,让我们开始吧。函数是为了避免重复代码,这可以在此处的多个级别上完成。 PowerShell中的函数需要在执行前声明,所以我倾向于把所有的函数集中在脚本的开头,像这样:
# *** FUNCTION DEFINITIONS
function Log-InstalledProgram($InstalledProgram, $LogFilePath)
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $LogFilePath -Value "Product Name: $logString" -Force
add-content -Path $LogFilePath -Value "Publisher: $logp" -Force
add-content -Path $LogFilePath -Value "Version: $logv" -Force
add-content -Path $LogFilePath -Value "InstallDate: $logd" -Force
add-content -Path $LogFilePath -Value "`n" -Force
}
# *** BEGIN MAIN SCRIPT
Clear-Host
#$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$scriptPath = $PSScriptRoot
$logFilePath= Join-path $scriptPath "TestResults.log"
#If log file exists, then clear its contents
if (Test-Path $logFilePath)
{
clear-content -Path $logFilePath
}
$log = "Date Of Testing: {0} " -f (Get-Date)
$logString = "Process Started."
add-content -Path $logFilePath -Value $log -Force
add-content -Path $logFilePath -Value $logString -Force
add-content -Path $logFilePath -Value "`n" -Force
#Validate ADD/Remove Program list
add-content -Path $logFilePath -Value "`n" -Force
add-content -Path $logFilePath -Value "Add/Remove Programs :" -Force
add-content -Path $logFilePath -Value "`n" -Force
$InstalledPrograms = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
add-content -Path $logFilePath -Value "`n" -Force
foreach ($InstalledProgram in $InstalledPrograms )
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Operational Control")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Management Studio")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("System Analyzer")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("STeP")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
}
您可以通过为所需程序添加一个内部循环来进一步减少代码:
foreach ($InstalledProgram in $InstalledPrograms )
{
foreach ($displayName in "Operational Control","Management Studio", "System Analyzer", "STeP")
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains($displayName)))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
}
}
还有其他的优化,例如你可以避免重复调用 Add-Content
因为 -Value
参数也接受一个数组作为参数,你可以使用哈希表来捕获你的对象属性想在日志文件中提取他们的显示名称等等。
如何编写一个函数来避免我的 powershell 脚本的重复代码,它基本上显示了我机器上安装的应用程序列表,这些应用程序来自控制面板中的添加和删除 window。
下面是powershell脚本
堆叠.ps1
Clear-Host
#$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$scriptPath = $PSScriptRoot
$logFilePath= Join-path $scriptPath "TestResults.log"
#If log file exists, then clear its contents
if (Test-Path $logFilePath)
{
clear-content -Path $logFilePath
}
$log = "Date Of Testing: {0} " -f (Get-Date)
$logString = "Process Started."
add-content -Path $logFilePath -Value $log -Force
add-content -Path $logFilePath -Value $logString -Force
add-content -Path $logFilePath -Value "`n" -Force
#Validate ADD/Remove Program list
add-content -Path $logFilePath -Value "`n" -Force
add-content -Path $logFilePath -Value "Add/Remove Programs :" -Force
add-content -Path $logFilePath -Value "`n" -Force
$InstalledPrograms = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
add-content -Path $logFilePath -Value "`n" -Force
foreach ($InstalledProgram in $InstalledPrograms )
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Operational Control")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Publisher: $logp" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force****
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Management Studio")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Publisher: $logp" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("System Analyzer")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Publisher: $logp" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("STeP")))
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $logFilePath -Value "Product Name: $logString" -Force
add-content -Path $logFilePath -Value "Version: $logv" -Force
add-content -Path $logFilePath -Value "InstallDate: $logd" -Force
add-content -Path $logFilePath -Value "`n" -Force
}
}
我说的是每个 if 语句下的代码,用于将输出复制到日志文件。我可以用函数替换该代码并在每个 if 语句中调用该函数吗?
好的,让我们开始吧。函数是为了避免重复代码,这可以在此处的多个级别上完成。 PowerShell中的函数需要在执行前声明,所以我倾向于把所有的函数集中在脚本的开头,像这样:
# *** FUNCTION DEFINITIONS
function Log-InstalledProgram($InstalledProgram, $LogFilePath)
{
$InstalledProgram | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
$logString = $InstalledProgram.DisplayName
$logp = $InstalledProgram.Publisher
$logv = $InstalledProgram.DisplayVersion
$logd= $InstalledProgram.InstallDate
add-content -Path $LogFilePath -Value "Product Name: $logString" -Force
add-content -Path $LogFilePath -Value "Publisher: $logp" -Force
add-content -Path $LogFilePath -Value "Version: $logv" -Force
add-content -Path $LogFilePath -Value "InstallDate: $logd" -Force
add-content -Path $LogFilePath -Value "`n" -Force
}
# *** BEGIN MAIN SCRIPT
Clear-Host
#$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$scriptPath = $PSScriptRoot
$logFilePath= Join-path $scriptPath "TestResults.log"
#If log file exists, then clear its contents
if (Test-Path $logFilePath)
{
clear-content -Path $logFilePath
}
$log = "Date Of Testing: {0} " -f (Get-Date)
$logString = "Process Started."
add-content -Path $logFilePath -Value $log -Force
add-content -Path $logFilePath -Value $logString -Force
add-content -Path $logFilePath -Value "`n" -Force
#Validate ADD/Remove Program list
add-content -Path $logFilePath -Value "`n" -Force
add-content -Path $logFilePath -Value "Add/Remove Programs :" -Force
add-content -Path $logFilePath -Value "`n" -Force
$InstalledPrograms = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
add-content -Path $logFilePath -Value "`n" -Force
foreach ($InstalledProgram in $InstalledPrograms )
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Operational Control")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("Management Studio")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("System Analyzer")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains("STeP")))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
}
您可以通过为所需程序添加一个内部循环来进一步减少代码:
foreach ($InstalledProgram in $InstalledPrograms )
{
foreach ($displayName in "Operational Control","Management Studio", "System Analyzer", "STeP")
{
if(($InstalledProgram.DisplayName -ne $Null) -and ($InstalledProgram.DisplayName.Contains($displayName)))
{
Log-InstalledProgram $InstalledProgram $logFilePath
}
}
}
还有其他的优化,例如你可以避免重复调用 Add-Content
因为 -Value
参数也接受一个数组作为参数,你可以使用哈希表来捕获你的对象属性想在日志文件中提取他们的显示名称等等。