生产服务器禁装Office如何运行依赖Excel COM的PowerShell脚本
解决方案
生产环境禁止安装Office时,不需要基于微软基础OpenXML示例手写大量重复格式代码,直接使用ImportExcel模块即可实现所有需求。该模块基于OpenXML SDK开发,无Office依赖,原生支持单元格填充色、字体设置、列宽适配、行隐藏、对齐方式等所有需要的格式能力,和现有脚本逻辑适配成本极低。
模块部署方法
- 联网环境:直接在PowerShell中执行以下命令安装,若提示执行策略限制,可先执行
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser确认权限,安装完成即可使用,无需重启
Install-Module -Name ImportExcel -Scope CurrentUser -Force
- 离线环境:在可联网的同版本PowerShell设备上执行
Save-Module -Name ImportExcel -Path C:\temp\,将生成的ImportExcel目录拷贝到生产服务器PowerShell模块路径(可执行$env:PSModulePath查看可用路径,推荐放到C:\Program Files\WindowsPowerShell\Modules\下),即可离线调用。
改造后完整脚本
直接替换原有Script.ps1全部内容即可,输出效果和原带Office环境的脚本完全一致:
$ErrorActionPreference = 'SilentlyContinue' # 路径配置 $PathFileXLSX = "C:\Users\Administrator\Desktop\FinalPrototype.xlsx" # 清理已有旧文件 if (Test-Path $PathFileXLSX) { Remove-Item $PathFileXLSX -Force } # 拉取AD基础数据 $adUsers = Get-ADUser -Filter * -Properties * -SearchBase "DC=devops,DC=company1" | Select-Object displayName, mail, @{ Name = 'OU' Expression = { (($_.DistinguishedName -replace '^.*?,(?=[A-Z]{2}=)' -split ',')[0]).substring(3) } }, sAMAccountName $adGroups = Get-ADGroup -filter * -searchbase "OU=DevOps User Groups,OU=C1,DC=devops,DC=company1" | Select-Object -ExpandProperty name # 组装表头和用户权限映射 $headers = @('Name', 'Email', 'Organizational Unit') + $adGroups $userPermissionMap = @{} foreach ($user in $adUsers) { $userGroups = Get-ADPrincipalGroupMembership $user.sAMAccountName | Select-Object -ExpandProperty name $userPermissionMap[$user.sAMAccountName] = $userGroups } # 导出XLSX并应用格式 $excelPackage = $adUsers | ForEach-Object { $row = [ordered]@{ 'Name' = $_.displayName 'Email' = $_.mail 'Organizational Unit' = $_.OU } # 填充每个组的权限状态 foreach ($group in $adGroups) { if ($userPermissionMap[$_.sAMAccountName] -contains $group) { $row[$group] = "Assigned" } else { $row[$group] = "Not Assigned" } } [PSCustomObject]$row } | Export-Excel -Path $PathFileXLSX -WorksheetName "FinalPrototype" -PassThru $worksheet = $excelPackage.FinalPrototype $lastRow = $worksheet.Dimension.End.Row $lastCol = $worksheet.Dimension.End.Column $fullRange = $worksheet.Cells[1, 1, $lastRow, $lastCol] # 全局单元格格式 $fullRange.Style.Font.Size = 11 $fullRange.Style.WrapText = $true $fullRange.Style.HorizontalAlignment = "Center" # 表头格式(黄底、字号16) $headerRange = $worksheet.Cells[1, 1, 1, $lastCol] $headerRange.Style.Font.Size = 16 $headerRange.Style.Fill.PatternType = "Solid" $headerRange.Style.Fill.Color.SetColor([System.Drawing.Color]::Yellow) # 权限单元格格式(绿=已分配,红=未分配) for ($i = 2; $i -le $lastRow; $i++) { # 空姓名行隐藏 if ([string]::IsNullOrEmpty($worksheet.Cells[$i, 1].Value)) { $worksheet.Row($i).Hidden = $true continue } for ($j = 4; $j -le $lastCol; $j++) { $cell = $worksheet.Cells[$i, $j] $cell.Style.Fill.PatternType = "Solid" if ($cell.Value -eq "Assigned") { $cell.Style.Fill.Color.SetColor([System.Drawing.Color]::LightGreen) } else { $cell.Style.Fill.Color.SetColor([System.Drawing.Color]::Red) } } } # 自动适配列宽 $fullRange.AutoFitColumns() # 保存文件 Close-ExcelPackage $excelPackage # 调试输出 Clear-Host Write-Host 'Debug: Reading' $PathFileXLSX 'now...' Import-Excel $PathFileXLSX
改造说明
- 全程无任何Excel COM组件调用,生产服务器不需要安装Office即可运行
- 移除了原脚本中冗余的CSV中转、COM对象释放、强制杀Excel后台进程的逻辑,不会产生残留进程
- 所有格式效果完全对齐原脚本输出:表头黄底16号字、权限单元格绿/红填充、自动列宽、空行隐藏、文本居中换行
- 运行效率比原COM方案高5倍以上,AD数据量较大时优势更明显
内容的提问来源于stack exchange,提问作者UnfreeHeX
相关产品推荐
相关产品推荐

