PowerShell 技能连载 - 供应链安全漏洞扫描工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function Invoke-SupplyChainScan {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$ScanPath,

[ValidateSet('Critical','High','Medium','Low')]
[string]$SeverityLevel = 'Critical'
)

$report = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
ScannedComponents = @()
SecurityFindings = @()
}

# 组件哈希校验
Get-ChildItem $ScanPath -Recurse -Include *.dll,*.exe,*.psm1 | ForEach-Object {
$fileHash = (Get-FileHash $_.FullName -Algorithm SHA256).Hash
$signature = Get-AuthenticodeSignature $_.FullName

$component = [PSCustomObject]@{
FileName = $_.Name
FilePath = $_.FullName
SHA256 = $fileHash
IsSigned = $signature.Status -eq 'Valid'
Publisher = $signature.SignerCertificate.Subject
}
$report.ScannedComponents += $component

if (-not $component.IsSigned) {
$report.SecurityFindings += [PSCustomObject]@{
Severity = 'High'
Description = "未签名的组件: $($_.Name)"
Recommendation = "要求供应商提供数字签名版本或验证组件来源"
}
}
}

# 依赖包漏洞扫描
$nugetPackages = Get-ChildItem $ScanPath -Recurse -Include packages.config
$nugetPackages | ForEach-Object {
[xml]$config = Get-Content $_.FullName
$config.packages.package | ForEach-Object {
$cveData = Invoke-RestMethod "https://api.cvecheck.org/v1/search?id=$($_.id)"
if ($cveData.vulnerabilities | Where-Object { $_.severity -ge $SeverityLevel }) {
$report.SecurityFindings += [PSCustomObject]@{
Severity = $SeverityLevel
Description = "存在漏洞的依赖包: $($_.id) v$($_.version)"
Recommendation = "升级到最新安全版本 $($cveData.latestVersion)"
}
}
}
}

$report | Export-Csv -Path "$ScanPath\SupplyChainReport_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
return $report
}

核心功能

  1. 软件组件供应链安全扫描
  2. 依赖包漏洞自动化检测
  3. 数字签名验证机制
  4. CVE漏洞数据库集成

典型应用场景

  • 开发环境第三方组件安全检查
  • 软件构建流水线安全审计
  • 供应商交付物合规验证
  • 企业软件资产安全基线报告生成

PowerShell 技能连载 - 零信任架构下的设备健康检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function Invoke-DeviceHealthCheck {
param(
[string[]]$ComputerNames = $env:COMPUTERNAME
)

$securityBaseline = @{
SecureBootEnabled = $true
TPMPresent = $true
BitLockerStatus = 'FullyEncrypted'
AntivirusStatus = 'Enabled'
FirewallProfile = 'Domain'
}

$results = @()

foreach ($computer in $ComputerNames) {
try {
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer
$tpm = Get-CimInstance -ClassName Win32_Tpm -ComputerName $computer -ErrorAction Stop
$bitlocker = Get-BitLockerVolume -MountPoint $osInfo.SystemDrive -ErrorAction Stop

$healthStatus = [PSCustomObject]@{
ComputerName = $computer
LastBootTime = $osInfo.LastBootUpTime
SecureBoot = [bool](Confirm-SecureBootUEFI)
TPMVersion = $tpm.SpecVersion
BitLockerProtection = $bitlocker.ProtectionStatus
DefenderStatus = (Get-MpComputerStatus).AntivirusEnabled
FirewallStatus = (Get-NetFirewallProfile -Name Domain).Enabled
ComplianceScore = 0
}

# 计算合规分数
$healthStatus.ComplianceScore = [math]::Round((
($healthStatus.SecureBoot -eq $securityBaseline.SecureBootEnabled) +
($healthStatus.TPMVersion -match '2.0') +
($healthStatus.BitLockerProtection -eq 'On') +
($healthStatus.DefenderStatus -eq $true) +
($healthStatus.FirewallStatus -eq $true)
) / 5 * 100, 2)

$results += $healthStatus
}
catch {
Write-Warning "$computer 健康检查失败: $_"
}
}

$results | Format-Table -AutoSize
}

核心功能:

  1. 自动化验证设备安全基线配置
  2. 检测TPM 2.0和SecureBoot状态
  3. 评估BitLocker加密状态
  4. 生成设备合规性评分

应用场景:

  • 零信任网络接入前检查
  • 远程办公设备安全审计
  • 合规性自动化报告生成

PowerShell 技能连载 - 多云成本优化自动化系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
function Get-CloudCostReport {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string[]]$SubscriptionIds,

[ValidateSet('Daily','Monthly')]
[string]$Granularity = 'Monthly'
)

$costReport = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
TotalCost = 0
ServiceBreakdown = @{}
OptimizationSuggestions = @()
}

try {
# 获取跨云成本数据
$costData = $SubscriptionIds | ForEach-Object {
Invoke-RestMethod -Uri "https://management.azure.com/subscriptions/$_/providers/Microsoft.CostManagement/query?api-version=2023-03-01" \
-Headers @{ Authorization = "Bearer $env:AZURE_TOKEN" } \
-Body (@{
type = "ActualCost"
timeframe = "MonthToDate"
dataset = @{
aggregation = @{
totalCost = @{
name = "Cost"
function = "Sum"
}
}
grouping = @(
@{
type = "Dimension"
name = "ServiceName"
}
)
}
} | ConvertTo-Json)
}

# 分析成本结构
$costReport.TotalCost = ($costData.properties.rows | Measure-Object -Property [0] -Sum).Sum
$costReport.ServiceBreakdown = $costData.properties.rows |
Group-Object { $_[1] } -AsHashTable |
ForEach-Object { @{$_.Key = [math]::Round($_.Value[0],2)} }

# 生成优化建议
$costData.properties.rows | Where-Object { $_[0] -gt 1000 } | ForEach-Object {
$costReport.OptimizationSuggestions += [PSCustomObject]@{
Service = $_[1]
Cost = $_[0]
Recommendation = "考虑预留实例或自动缩放配置"
}
}
}
catch {
Write-Error "成本数据获取失败: $_"
}

# 生成Excel格式报告
$costReport | Export-Excel -Path "$env:TEMP/CloudCostReport_$(Get-Date -Format yyyyMMdd).xlsx"
return $costReport
}

核心功能

  1. 跨云成本数据聚合分析
  2. 服务维度费用结构分解
  3. 智能优化建议生成
  4. Excel格式报告输出

应用场景

  • 多云环境成本监控
  • 预算超支预警
  • 资源使用效率优化
  • 财务部门合规报告

PowerShell参数传递机制详解

参数传递基础原理

1
2
3
4
5
6
7
8
9
# 位置参数示例
function Get-FullName {
param($FirstName, $LastName)
"$FirstName $LastName"
}
Get-FullName '张' '三'

# 命名参数示例
Get-FullName -LastName '李' -FirstName '四'

管道参数绑定

1
2
3
4
1..5 | ForEach-Object { 
param([int]$num)
$num * 2
}

实用技巧

  1. 使用[Parameter(Mandatory)]标记必选参数
  2. 通过ValueFromPipeline实现流式处理
  3. 验证集ValidateSet限制参数取值范围
  4. 类型转换失败时的错误处理策略

PowerShell集合类型操作指南

基础数据结构

1
2
3
4
5
6
7
# 数组初始化与索引
$numbers = 1..5
$numbers[0] = 10 # 索引从0开始

# 哈希表键值操作
$user = @{Name='Alice'; Age=25}
$user['Department'] = 'IT'

操作对比表

方法 数组适用 哈希表适用 时间复杂度
Add() × O(1)
Remove() × O(1)
Contains() O(n)/O(1)

典型应用场景

  1. 使用ArrayList实现动态数组
  2. 通过OrderedDictionary保持插入顺序
  3. 利用哈希表进行快速键值查找
  4. 多维数组存储表格数据

常见错误解析

1
2
3
4
5
6
7
# 固定大小数组修改错误
$fixedArray = @(1,2,3)
$fixedArray.Add(4) # 抛出异常

# 正确使用动态集合
$list = [System.Collections.ArrayList]@(1,2,3)
$list.Add(4) | Out-Null

PowerShell管道过滤器实战指南

管道过滤器原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 基础过滤示例
Get-Process | Where-Object {$_.CPU -gt 100} | Select-Object Name, Id

# 自定义过滤函数
function Filter-LargeFiles {
param([int]$SizeMB=50)
Process {
if ($_.Length -gt $SizeMB*1MB) {
$_
}
}
}

Get-ChildItem -Recurse | Filter-LargeFiles -SizeMB 100

性能优化要点

  1. 尽量在管道前端过滤
  2. 避免在过滤器中执行耗时操作
  3. 合理使用流式处理与缓存机制

典型应用场景

1
2
3
4
5
6
# 实时监控进程创建
Get-WmiObject -Query "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'" |
ForEach-Object {
$process = $_.TargetInstance
Write-Host "新进程: $($process.Name) (PID: $($process.ProcessId))"
}

调试技巧

1
2
3
# 查看中间结果
Get-Service | Tee-Object -Variable temp | Where-Object Status -eq 'Running'
$temp | Format-Table -AutoSize

PowerShell JEA安全架构解析

JEA端点配置

1
2
3
4
5
6
7
8
# 创建会话配置文件
$sessionParams = @{
Path = '.JEAConfig.pssc'
SessionType = 'RestrictedRemoteServer'
RunAsVirtualAccount = $true
RoleDefinitions = @{ 'CONTOSO\SQLUsers' = @{ RoleCapabilities = 'SqlReadOnly' } }
}
New-PSSessionConfigurationFile @sessionParams

角色能力定义

1
2
3
4
5
6
7
8
9
# 创建角色能力文件
$roleCapability = @{
Path = 'Roles\SqlReadOnly.psrc'
VisibleCmdlets = 'Get-Sql*'
VisibleFunctions = 'ConvertTo-Query'
VisibleProviders = 'FileSystem'
ScriptsToProcess = 'Initialize-SqlEnv.ps1'
}
New-PSRoleCapabilityFile @roleCapability

会话沙箱验证

1
2
3
4
5
6
# 连接JEA端点并验证权限
$session = New-PSSession -ConfigurationName JEAConfig
Invoke-Command -Session $session {
Get-Command -Name * # 仅显示白名单命令
Get-ChildItem C:\ # 触发权限拒绝
}

典型应用场景

  1. 数据库只读访问控制
  2. 第三方供应商操作审计
  3. 生产环境故障诊断隔离
  4. 跨域资源受限访问

安全加固要点

  • 虚拟账户生命周期控制
  • 转录日志完整性校验
  • 模块白名单签名验证
  • 会话超时熔断机制

PowerShell 技能连载 - Azure Functions 管理技巧

在 PowerShell 中管理 Azure Functions 是一项重要任务,本文将介绍一些实用的 Azure Functions 管理技巧。

首先,让我们看看基本的 Azure Functions 操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 创建 Azure Functions 信息获取函数
function Get-AzFunctionInfo {
param(
[string]$FunctionAppName,
[string]$ResourceGroupName
)

try {
$functionApp = Get-AzFunctionApp -Name $FunctionAppName -ResourceGroupName $ResourceGroupName
$functions = Get-AzFunction -FunctionAppName $FunctionAppName -ResourceGroupName $ResourceGroupName

return [PSCustomObject]@{
Name = $functionApp.Name
ResourceGroup = $functionApp.ResourceGroup
Location = $functionApp.Location
Runtime = $functionApp.Runtime
OS = $functionApp.OSType
State = $functionApp.State
FunctionCount = $functions.Count
Functions = $functions | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
Trigger = $_.Trigger
Status = $_.Status
}
}
}
}
catch {
Write-Host "获取函数应用信息失败:$_"
}
}

Azure Functions 部署:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 创建 Azure Functions 部署函数
function Deploy-AzFunction {
param(
[string]$FunctionAppName,
[string]$ResourceGroupName,
[string]$PackagePath,
[string]$Runtime,
[hashtable]$AppSettings
)

try {
# 创建部署包
$zipPath = "$PackagePath.zip"
Compress-Archive -Path $PackagePath -DestinationPath $zipPath -Force

# 部署函数应用
$functionApp = New-AzFunctionApp -Name $FunctionAppName `
-ResourceGroupName $ResourceGroupName `
-Runtime $Runtime `
-StorageAccountName (New-AzStorageAccount -Name "$($FunctionAppName)storage" `
-ResourceGroupName $ResourceGroupName `
-Location (Get-AzResourceGroup -Name $ResourceGroupName).Location `
-SkuName Standard_LRS).StorageAccountName `
-FunctionsVersion 4 `
-OSType Windows `
-RuntimeVersion 7.0 `
-AppSettings $AppSettings

# 部署函数代码
Publish-AzWebApp -Name $FunctionAppName `
-ResourceGroupName $ResourceGroupName `
-ArchivePath $zipPath

# 清理临时文件
Remove-Item $zipPath

Write-Host "函数应用部署完成"
}
catch {
Write-Host "部署失败:$_"
}
}

Azure Functions 监控:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 创建 Azure Functions 监控函数
function Monitor-AzFunction {
param(
[string]$FunctionAppName,
[string]$ResourceGroupName,
[int]$Interval = 60,
[int]$Duration = 3600
)

try {
$startTime = Get-Date
$metrics = @()

while ((Get-Date) - $startTime).TotalSeconds -lt $Duration {
$invocations = Get-AzMetric -ResourceId (Get-AzFunctionApp -Name $FunctionAppName -ResourceGroupName $ResourceGroupName).Id `
-MetricName "FunctionExecutionUnits" `
-TimeGrain 1 `
-StartTime (Get-Date).AddMinutes(-5) `
-EndTime (Get-Date)

$errors = Get-AzMetric -ResourceId (Get-AzFunctionApp -Name $FunctionAppName -ResourceGroupName $ResourceGroupName).Id `
-MetricName "FunctionExecutionCount" `
-TimeGrain 1 `
-StartTime (Get-Date).AddMinutes(-5) `
-EndTime (Get-Date)

$metrics += [PSCustomObject]@{
Timestamp = Get-Date
Invocations = $invocations.Data | Measure-Object -Property Total -Sum | Select-Object -ExpandProperty Sum
Errors = $errors.Data | Measure-Object -Property Total -Sum | Select-Object -ExpandProperty Sum
MemoryUsage = Get-AzMetric -ResourceId (Get-AzFunctionApp -Name $FunctionAppName -ResourceGroupName $ResourceGroupName).Id `
-MetricName "MemoryUsage" `
-TimeGrain 1 `
-StartTime (Get-Date).AddMinutes(-5) `
-EndTime (Get-Date) |
Select-Object -ExpandProperty Data |
Measure-Object -Property Total -Average |
Select-Object -ExpandProperty Average
}

Start-Sleep -Seconds $Interval
}

return $metrics
}
catch {
Write-Host "监控失败:$_"
}
}

Azure Functions 日志收集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 创建 Azure Functions 日志收集函数
function Get-AzFunctionLogs {
param(
[string]$FunctionAppName,
[string]$ResourceGroupName,
[string]$FunctionName,
[datetime]$StartTime,
[datetime]$EndTime,
[ValidateSet("Information", "Warning", "Error")]
[string[]]$LogLevels
)

try {
$logs = Get-AzLog -ResourceId (Get-AzFunctionApp -Name $FunctionAppName -ResourceGroupName $ResourceGroupName).Id `
-StartTime $StartTime `
-EndTime $EndTime

if ($FunctionName) {
$logs = $logs | Where-Object { $_.ResourceName -eq $FunctionName }
}

if ($LogLevels) {
$logs = $logs | Where-Object { $_.Level -in $LogLevels }
}

return [PSCustomObject]@{
FunctionApp = $FunctionAppName
Function = $FunctionName
Logs = $logs
Summary = [PSCustomObject]@{
TotalCount = $logs.Count
ByLevel = $logs | Group-Object Level | ForEach-Object {
[PSCustomObject]@{
Level = $_.Name
Count = $_.Count
}
}
}
}
}
catch {
Write-Host "日志收集失败:$_"
}
}

Azure Functions 配置管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 创建 Azure Functions 配置管理函数
function Manage-AzFunctionConfig {
param(
[string]$FunctionAppName,
[string]$ResourceGroupName,
[hashtable]$AppSettings,
[switch]$RemoveUnspecified
)

try {
$functionApp = Get-AzFunctionApp -Name $FunctionAppName -ResourceGroupName $ResourceGroupName

if ($RemoveUnspecified) {
# 删除未指定的设置
$currentSettings = $functionApp.AppSettings
$currentSettings.Keys | ForEach-Object {
if (-not $AppSettings.ContainsKey($_)) {
$AppSettings[$_] = $null
}
}
}

# 更新应用设置
Update-AzFunctionApp -Name $FunctionAppName `
-ResourceGroupName $ResourceGroupName `
-AppSettings $AppSettings

Write-Host "配置更新完成"
}
catch {
Write-Host "配置更新失败:$_"
}
}

这些技巧将帮助您更有效地管理 Azure Functions。记住,在处理 Azure Functions 时,始终要注意应用的安全性和性能。同时,建议使用适当的监控和日志记录机制来跟踪函数的运行状态。

PowerShell 技能连载 - 高级参数处理

动态参数机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Get-EnvironmentData {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$EnvironmentName
)

dynamicparam {
$paramDictionary = New-Object Management.Automation.RuntimeDefinedParameterDictionary

if ($EnvironmentName -eq 'Production') {
$attribute = [System.Management.Automation.ParameterAttribute]@{
Mandatory = $true
HelpMessage = "生产环境专属参数"
}
$param = New-Object Management.Automation.RuntimeDefinedParameter(
'ProductionKey',
[string],
$attribute
)
$paramDictionary.Add('ProductionKey', $param)
}
return $paramDictionary
}
}

参数集应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Set-SystemConfiguration {
[CmdletBinding(DefaultParameterSetName='Basic')]
param(
[Parameter(ParameterSetName='Basic', Mandatory=$true)]
[string]$BasicConfig,

[Parameter(ParameterSetName='Advanced', Mandatory=$true)]
[string]$AdvancedConfig,

[Parameter(ParameterSetName='Advanced')]
[ValidateRange(1,100)]
[int]$Priority
)
# 根据参数集执行不同逻辑
}

最佳实践

  1. 使用Parameter属性定义清晰的参数关系
  2. 为复杂场景设计参数集
  3. 通过dynamicparam实现条件参数
  4. 保持参数命名的语义清晰

```powershell
function Invoke-CustomOperation {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
[ValidateScript({
if ($_.OperationType -notin ‘Read’,’Write’) {
throw “无效的操作类型”
}
$true
})]
[object]$InputObject
)
# 管道参数处理逻辑
}