You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PowerShell获取EFS加密文件所有者?求.NET替代方案

获取EFS加密文件所有者的PowerShell与.NET方案

一、优化PowerShell解析cipher.exe /c输出

直接调用cipher.exe /c后,可通过正则匹配批量提取所有者信息,替代手动查看:

$targetPath = "C:\Path\To\Your\EncryptedFile.txt"
# 跳过cipher输出的前4行表头内容
$cipherOutput = cipher.exe /c $targetPath | Select-Object -Skip 4 

foreach ($line in $cipherOutput) {
    if ($line -match "^.*?Owner:\s+(.*)$") {
        $owner = $matches[1].Trim()
        Write-Host "EFS所有者: $owner"
    }
}

二、.NET方案:通过P/Invoke调用Win32 API

.NET无原生类直接暴露EFS所有者信息,但可调用Windows系统APIQueryUsersOnEncryptedFile实现:

using System;
using System.Runtime.InteropServices;
using System.Text;

public class EfsHelper
{
    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool QueryUsersOnEncryptedFile(
        string lpFileName,
        ref uint lpdwUsers,
        IntPtr lpUserSidList,
        ref uint lpdwSidListSize,
        IntPtr lpUserDisplayNameList,
        ref uint lpdwDisplayNameListSize);

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool ConvertSidToStringSid(IntPtr pSid, out IntPtr lpString);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr LocalFree(IntPtr hMem);

    public static string GetEfsOwner(string filePath)
    {
        uint userCount = 0;
        uint sidListSize = 0;
        uint displayNameSize = 0;

        // 首次调用获取所需缓冲区大小
        QueryUsersOnEncryptedFile(filePath, ref userCount, IntPtr.Zero, ref sidListSize, IntPtr.Zero, ref displayNameSize);

        IntPtr sidList = Marshal.AllocHGlobal((int)sidListSize);
        IntPtr displayNameList = Marshal.AllocHGlobal((int)displayNameSize);

        try
        {
            if (QueryUsersOnEncryptedFile(filePath, ref userCount, sidList, ref sidListSize, displayNameList, ref displayNameSize))
            {
                // 第一个SID对应文件所有者
                IntPtr firstSid = Marshal.ReadIntPtr(sidList);
                if (ConvertSidToStringSid(firstSid, out IntPtr sidString))
                {
                    string sid = Marshal.PtrToStringUni(sidString);
                    LocalFree(sidString);
                    return sid;
                }
            }
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        }
        finally
        {
            Marshal.FreeHGlobal(sidList);
            Marshal.FreeHGlobal(displayNameList);
        }
    }
}

在PowerShell中直接加载该类并使用:

Add-Type -TypeDefinition @"
// 粘贴上述C#代码
"@

$ownerSid = [EfsHelper]::GetEfsOwner("C:\Path\To\Your\EncryptedFile.txt")
Write-Host "EFS所有者SID: $ownerSid"

# 可选:将SID转换为可读用户名
$account = New-Object System.Security.Principal.SecurityIdentifier($ownerSid)
$ownerName = $account.Translate([System.Security.Principal.NTAccount]).Value
Write-Host "EFS所有者用户名: $ownerName"

三、补充方案:WMI/CIM查询(卷级场景适用)

若需结合卷级加密信息,可通过Win32_EncryptableVolume类间接关联,但更适合批量卷管理,文件级场景优先使用前两种方案:

$filePath = "C:\Path\To\Your\EncryptedFile.txt"
$volume = Get-CimInstance -ClassName Win32_EncryptableVolume -Filter "DriveLetter='$((Get-Item $filePath).PSDrive.Name):'"
# 可结合其他WMI类进一步提取EFS用户信息

内容的提问来源于stack exchange,提问作者Zaver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:36:09