远程连接WMI ,HRESULT:0x80070005 (E_ACCESSDENIED))

Environment:  local -1703/remote-1709: Win10 Pro 64bit 

Preparasion:

1. local/remote都启动WS-Man服务即WinRM .  local启动winrm -quickstart. 添加所有机器(即*)到trustedhosts里. remote端只quickstart

     Ref: http://labs.supinfochina.com/en/powershell-configure-winrm-and-enable-psremoting/#_Toc429317714

2. 保证local/remote的WMI service在运行

3. 保证local访问root\cimv2没问题(用wbemtest.exe)

4. 关闭remote防火墙(所有)

问题:

1. 本来想玩转WMI的一个自带工具,C:\windows\system32\wbem\Wbemtest.exe ,结果这个工具connect同网络同workgroup的另一台机器被拒绝(我用的remote的admin用户),得到错误0x80070005!!

2. 想到MI已经取代WMI, WS-Man应该也可以,remote端Powershell启用Enable-PSRemoting。local的Powershell使用Get-WSManInstance -ResourceURI wmicimv2/win32_service -SelectorSet @{name="winrm"} -ComputerName "Server01" -credential admin (我用的remote的admin用户), 结果还是错误<f:WSManFault xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="5" Machine="xxx"><f:Message>拒绝访问。 </f:Message>

3. 用C#代码通过WS-Man协议IEnumerable<CimInstance> enumeratedInstances = cimSession.EnumerateInstances(cimNamespace, cimClassName);

    也会得到同样错误

解决方法
     方案A:  Remote端的注册表里添加特定valuename/value.
       KEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/ 下添加LocalAccountTokenFilterPolicy,类型REG_WORD,值1. 然后尝试之前2种方法,都成功!!

    Ref: https://blog.techygeekshome.info/2014/02/remote-uac-access-denied-errors-local-account-token-filter-policy-remote-uac-fix/

     优点:方便,快. 无论wbemtest.exe/powershell/C#使用都畅通无阻。

      缺点:这种方法其实是disable了remote UAC !!!对于学习或偷懒来说方便,用管理员账户登录就完全是管理员权限了,但是安全性就下降许多。


原因: "WMI tasks remotely accessing WMI information on this computer and requiring Administrative privileges MUST use a DOMAIN account part of the Local Administrators group of this computer to ensure that administrative privileges are granted. If a Local User account is used for remote accesses, it will be reduced to a plain user (filtered token), even if it is part of the Local Administrators group."
   Ref : https://serverfault.com/questions/713643/windows-10-wmi-and-event-viewer-access-denied

    MSDN描述---In a workgroup, the account connecting to the remote computer is a local user on that computer. Even if the account is in the Administrators group, UAC filtering means that a script runs as a standard user

            即使你用的remote端具有管理员权限的账户链接,UAC会把它降级为标准用户,所以本地端绝大多数访问都会被拒绝

   Ref: https://msdn.microsoft.com/en-us/library/aa826699(v=vs.85).aspx#handling_remote_connections_under_uac

方案B: 根据MSDN描述,创建只用于remote的用户与用户组,再在WMI Control(Computer Management)里,指定该用户(组)能访问哪些Namespace。比如我就创建了一个onlyRemote用户,只属于Remote Management Users但不属于administrators。

优点:安全!!

缺点:要花时间配置好Namespace范围。很多security object会要求administrator权限,在Powershell里或C#用我的onlyRemote(同时也在Administrators组里)访问Win32_Service就会出现Access Denied了,访问Win32_process不会。而我的wbemtest.exe用onlyRemote用户连接remote被完全拒绝.           

Ref: https://social.technet.microsoft.com/Forums/lync/en-US/4f33837b-1cb1-4648-85b1-3ba87cbfe93e/wmi-remote-access-denied?forum=winserverManagement

     DCOM应该是限制老式WMI的,如果不用Ws-Man访问,就还要在DCOM里指定remote权限. 通过dcomcnfg.exe修改DCOM security

PS: 在诊断Access Denied问题还用到了WMIDiag,可以辅助判断WMI潜在的问题,这次这个问题就是通过它提示发现的。


<think>我们面对的是在服务器环境中使用ExcelCOM组件时出现的权限问题(错误0x80070005)。根据引用内容,特别是引用[4]和[5]提供的解决方案,核心问题在于DCOM配置中缺少执行账户的本地激活权限。###解决方案步骤####1.确认执行账户首先确定运行应用程序的账户(如IIS中的应用程序池账户或计划任务账户)。引用[4]中提到的账户是`JEFFBOX\jeffrey`。####2.修改DCOM配置按以下步骤配置Excel应用程序的DCOM权限:1.打开组件服务管理器:-按`Win+R`,输入`dcomcnfg`并回车(32位系统)或`mmccomexp.msc/32`(64位系统上的32位组件)2.导航到DCOM配置:-控制台根节点→组件服务→计算机→我的电脑→DCOM配置3.找到MicrosoftExcel应用程序:-在列表中找到“MicrosoftExcelApplication”(CLSID:{00024500-0000-0000-C000-000000000046})4.配置权限:-右键选择“属性”,切换到“安全”选项卡-在三个权限区域(启动和激活权限、访问权限、配置权限)均选择“自定义”,然后点击“编辑”5.添加执行账户并赋予权限:-添加应用程序运行账户(如`IIS_IUSRS`、`NETWORKSERVICE`或特定用户)-勾选“本地激活”(LocalActivation)权限(启动和激活权限)-勾选“本地访问”(LocalAccess)权限(访问权限)-配置权限根据需要设置(通常默认即可)>**注意**:在服务器环境中,如果应用程序池使用虚拟账户(如IIS7+中的`IISAPPPOOL\DefaultAppPool`),需在DCOM配置中添加该账户[^5]。####3.调整身份验证级别(可选)在DCOM配置的“常规”选项卡中,将身份验证级别设为“无”:```plaintext身份验证级别:无```####4.设置标识(Identity)在“标识”选项卡中,选择“交互式用户”或指定有权限的用户:```plaintext标识:交互式用户```>**警告**:使用“交互式用户”要求服务器始终有用户登录,不推荐用于生产环境。更好的做法是创建专用服务账户。####5.重置COM组件权限(高级)如果问题仍然存在,使用组件服务重置计算机范围的COM权限:1.右键“我的电脑”→属性2.切换到“COM安全”选项卡3.在“访问权限”和“启动与激活权限”区域点击“编辑默认值”4.添加执行账户并赋予“本地激活”和“本地访问”权限####6.注册表权限调整(极端情况)如果上述方法无效,检查注册表项权限:```regHKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}```赋予执行账户“完全控制”权限(谨慎操作)。###服务器环境最佳实践1.**专用服务账户**:-创建域账户加入`DistributedCOMUsers`组-在DCOM配置中使用此账户作为标识2.**避免COM在服务端使用**:-改用OpenXMLSDK(`DocumentFormat.OpenXml`)-使用第三方库(如EPPlus、NPOI)```csharp//EPPlus示例using(varpackage=newExcelPackage(newFileInfo("output.xlsx"))){varsheet=package.Workbook.Worksheets.Add("Sheet1");sheet.Cells["A1"].Value="HelloWorld";package.Save();}```3.**权限最小化**:-仅授予必要的DCOM权限(避免完全控制)###故障排除流程```mermaidgraphTDA[出现0x80070005错误]-->B{是否服务器环境?}B-->|是|C[确认执行账户]B-->|否|D[检查本地账户权限]C-->E[配置DCOM权限]E-->F{问题解决?}F-->|否|G[尝试重置COM默认权限]G-->H{问题解决?}H-->|否|I[检查注册表权限]I-->J[考虑替代方案]```>**关键提示**:微软官方明确表示OfficeCOM组件不支持服务器端自动化[^3]。生产环境应优先使用无界面解决方案。§§相关问题§§1.如何为IIS应用程序池账户配置DCOM权限?2.使用OpenXMLSDK处理Excel有哪些优势?3.如何监控和调试DCOM权限问题?4.在ASP.NETCore中如何避免使用COM生成Excel文件?[^1]:错误0x80070005表明账户缺少DCOM激活权限[^2]:服务器部署时需额外配置DCOM权限[^3]:微软建议服务器端避免使用OfficeCOM组件[^4]:DCOM配置工具是解决权限问题的关键[^5]:添加应用程序池账户到DCOM权限可解决访问拒绝问题</think>## 解决 Excel COM 类工厂访问拒绝错误 (0x80070005) ### 错误原因分析 `Retrieving the COM class factory for Excel CLSID {00024500-0000-0000-C000-000000000046} failed with error 0x80070005` 是典型的 **DCOM 权限配置问题**,常见于服务器环境部署时。核心原因包括: 1. **执行账户缺少 DCOM 激活权限**:运行程序的账户(如 IIS 应用池账户)未被授予 Excel COM 组件的本地激活权限[^4] 2. **DCOM 默认权限不足**:系统级 DCOM 配置未包含执行账户的必要权限[^4] 3. **组件安全设置错误**:Excel 应用程序的 COM 安全设置未正确配置[^5] 4. **身份验证级别问题**:服务器与 COM 组件间的身份验证级别不匹配 --- ### 完整解决方案 (分步操作) #### 步骤 1: 配置 DCOM 权限 (核心解决步骤) 1. 以管理员身份运行命令: ```cmd mmc comexp.msc /32 # 打开32位组件服务(关键!) ``` 2. 导航至: ``` 组件服务 → 计算机 → 我的电脑 → DCOM 配置 ``` 3. 找到 **Microsoft Excel 应用程序** (CLSID: `{00024500-0000-0000-C000-000000000046}`) 4. 右键 → 属性 → 安全选项卡 5. 配置三个关键区域: - **启动和激活权限** → 自定义 → 编辑 - 添加执行账户 (如 `IIS_IUSRS`, `NETWORK SERVICE` 或特定用户) - 勾选 **本地激活** (Local Activation)[^4][^5] - **访问权限** → 自定义 → 编辑 - 添加相同账户 - 勾选 **本地访问** (Local Access) - **配置权限** → 自定义 → 编辑 - 添加账户并赋予完全控制 #### 步骤 2: 设置标识和身份验证 1. 在 Excel 应用程序属性中切换到 **标识** 选项卡: - 选择 **交互式用户** (测试环境) 或 **指定用户** (生产环境) 2. 切换到 **常规** 选项卡: - 设置 **身份验证级别** 为 **无** #### 步骤 3: 注册表权限修复 (备用方案) 1. 打开注册表编辑器 (`regedit`) 2. 导航至: ``` HKEY_CLASSES_ROOT\AppID\{00024500-0000-0000-C000-000000000046} ``` 3. 右键 → 权限 → 添加执行账户 4. 赋予 **完全控制** 权限 #### 步骤 4: 服务器环境专用配置 ```powershell # 为 IIS 应用池账户授权 $account = "IIS APPPOOL\YourAppPoolName" $com = Get-WmiObject -Namespace "root\cimv2" -Class Win32_DCOMApplicationSetting | Where-Object { $_.AppId -eq "{00024500-0000-0000-C000-000000000046}" } $com.SetLaunchAndActivationPermissions($account, $true, $true, $true, $true) ``` --- ### 服务器环境最佳实践 1. **创建专用服务账户**: - 避免使用 `NETWORK SERVICE`,创建域账户加入 `Distributed COM Users` 组 - 在 DCOM 配置中使用此专用账户作为标识 2. **组件服务优化**: ```mermaid graph LR A[应用程序池] --> B(专用服务账户) B --> C{DCOM配置} C --> D[启动权限=本地激活] C --> E[访问权限=本地访问] C --> F[标识=指定用户] ``` 3. **替代方案 (推荐)**: ```csharp // 使用 OpenXML 替代 COM (无权限问题) using (var doc = SpreadsheetDocument.Create("report.xlsx", SpreadsheetDocumentType.Workbook)) { WorkbookPart workbookPart = doc.AddWorkbookPart(); workbookPart.Workbook = new Workbook(); // ... 添加工作表和数据 } ``` --- ### 验证与测试 1. 在事件查看器中检查: ``` 应用程序和服务日志 → Microsoft → Windows → DCOM-Activation ``` 2. 确认无新的 `Access Denied` 错误 3. 使用 PowerShell 测试: ```powershell $excel = New-Object -ComObject Excel.Application -Strict $excel.Visible = $true $excel.Quit() ``` > **关键提示**:微软官方不建议在服务器端使用 Office COM 组件[^2],生产环境优先考虑 OpenXML SDK 或 EPPlus 等替代方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值