如何使用.NET远程扩展环境变量?

发布于 2024-10-18 01:31:14 字数 242 浏览 4 评论 0原文

我需要一种在远程计算机上扩展环境变量的方法。

假设我有一个文件夹 %appdata%\MyApp\Plugins%ProgramFiles%\MyCompany\MyApp\Plugins 的路径,并且我想列出该文件夹中的文件以供审核目的。唯一的问题是我想在远程计算机上执行此操作,但我具有管理员访问权限。

一个额外的问题(但不是必需的)是如何为远程计算机上的给定用户执行此操作?

I need a way to expand environment variable on a remote machine.

Suppose I have a path to a folder %appdata%\MyApp\Plugins or %ProgramFiles%\MyCompany\MyApp\Plugins and I want to list files in that folder for audit purposes. The only problem is I want to do it on a remote machine, which however I have admin access to.

An extra question (but not essential) is how to do that for given user on remote machine?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

对你的占有欲 2024-10-25 01:31:14

您可以使用 GetFolderPath。您可以使用许多不同的 SpecialFolder 值,包括 ProgramFilesApplicationData

string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);

然后您可以将其与路径的其余部分结合起来

string full_path = Path.Combine(path, "\MyApp\Plugins");

在远程计算机上,看起来您可以尝试类似

ConnectionOptions co = new ConnectionOptions();
// user with sufficient privileges to connect to the cimv2 namespace
co.Username = "administrator"; 
// his password
co.Password = "adminPwd";
ManagementScope scope = new ManagementScope(@"\\BOBSMachine\root\cimv2", co);
SelectQuery query = new SelectQuery("Select windowsdirectory from Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject windir in searcher.Get())
   Console.WriteLine("Value = {0}", windir["windowsdirectory"]);

或者获取所有远程环境变量及其值的列表,来自 此处

public static void GetSysInfo(string domain, string machine, string username, string password)
{
    ManagementObjectSearcher query = null;
    ManagementObjectCollection queryCollection = null;

    ConnectionOptions opt = new ConnectionOptions(); 

    opt.Impersonation = ImpersonationLevel.Impersonate; 
    opt.EnablePrivileges = true; 
    opt.Username = username; 
    opt.Password = password; 
    try 
    { 
        ManagementPath p = new ManagementPath("\\\\" +machine+ "\\root\\cimv2");   

        ManagementScope msc = new ManagementScope(p, opt); 

        SelectQuery q= new SelectQuery("Win32_Environment");

        query = new ManagementObjectSearcher(msc, q, null); 
        queryCollection = query.Get(); 

        Console.WriteLine(queryCollection.Count);

        foreach (ManagementBaseObject envVar in queryCollection) 
        {
            Console.WriteLine("System environment variable {0} = {1}", 
            envVar["Name"], envVar["VariableValue"]);
        }
    } 
    catch(ManagementException e) 
    { 
        Console.WriteLine(e.Message); 
        Environment.Exit(1); 
    } 
    catch(System.UnauthorizedAccessException e) 
    { 
        Console.WriteLine(e.Message); 
        Environment.Exit(1); 
    } 
}

OP编辑:
此外,还可以从位于 HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell 文件夹 的注册表(可远程完成)和位于 的程序文件中找到 %AppData% >HKLM\Software\Microsoft\Windows\CurrentVersion,位于 ProgramfilesDir 下。

You would use GetFolderPath. There are a bunch of different SpecialFolder values that you could use including ProgramFiles and ApplicationData

string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);

Then you could just combine it with the rest of your path

string full_path = Path.Combine(path, "\MyApp\Plugins");

On a remote machine, it looks like you can try something like this

ConnectionOptions co = new ConnectionOptions();
// user with sufficient privileges to connect to the cimv2 namespace
co.Username = "administrator"; 
// his password
co.Password = "adminPwd";
ManagementScope scope = new ManagementScope(@"\\BOBSMachine\root\cimv2", co);
SelectQuery query = new SelectQuery("Select windowsdirectory from Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject windir in searcher.Get())
   Console.WriteLine("Value = {0}", windir["windowsdirectory"]);

Or for a list of all remote environment variables and their values, from here

public static void GetSysInfo(string domain, string machine, string username, string password)
{
    ManagementObjectSearcher query = null;
    ManagementObjectCollection queryCollection = null;

    ConnectionOptions opt = new ConnectionOptions(); 

    opt.Impersonation = ImpersonationLevel.Impersonate; 
    opt.EnablePrivileges = true; 
    opt.Username = username; 
    opt.Password = password; 
    try 
    { 
        ManagementPath p = new ManagementPath("\\\\" +machine+ "\\root\\cimv2");   

        ManagementScope msc = new ManagementScope(p, opt); 

        SelectQuery q= new SelectQuery("Win32_Environment");

        query = new ManagementObjectSearcher(msc, q, null); 
        queryCollection = query.Get(); 

        Console.WriteLine(queryCollection.Count);

        foreach (ManagementBaseObject envVar in queryCollection) 
        {
            Console.WriteLine("System environment variable {0} = {1}", 
            envVar["Name"], envVar["VariableValue"]);
        }
    } 
    catch(ManagementException e) 
    { 
        Console.WriteLine(e.Message); 
        Environment.Exit(1); 
    } 
    catch(System.UnauthorizedAccessException e) 
    { 
        Console.WriteLine(e.Message); 
        Environment.Exit(1); 
    } 
}

OP Edit:
Also %AppData% can be found from registry (can be done remotely) at HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders and Program Files at HKLM\Software\Microsoft\Windows\CurrentVersion, under ProgramfilesDir.

萧瑟寒风 2024-10-25 01:31:14

这个问题没有意义。环境变量不是每台机器的变量。例如,您可以期望 %appdata% 指向 C:\users\ 目录,但具体位置显然取决于用户。以管理员身份登录仍然无法帮助您;这只会告诉您管理员的 %appdata% 在哪里。

The question doesn't make sense. Environment variables are not per-machine variables. For instance, you can expect %appdata% to point inside the C:\users\ directory, but precisely where obviously depends to the user. Logging in as admin still doesn't help you; that would merely tell you where the admin's %appdata% is.

孤凫 2024-10-25 01:31:14

环境变量是“计算机范围内的设置”和“每个用户设置”的合并。正在运行的进程可能修改其环境,并且当它生成另一个进程时,该进程将继承创建它的进程的环境。

除非您有权访问远程计算机上运行的进程(或者可以启动一个进程),否则不存在“环境”这样的东西:它的上下文根本不存在。特定进程的环境是以下各项的函数:

  • 从父进程的环境继承的环境(可能在与子进程不同的用户帐户下运行。)
  • 计算机范围的环境设置。
  • 用户指定的任何环境设置。
  • 流程本身所做的任何更改。

也就是说,Windows 将其环境变量设置保留在注册表中:

  • 用户变量。
    HKEY_CURRENT_USER\Environment
  • 系统变量。
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\环境

如果您对远程计算机的注册表有适当的访问权限,您应该能够找到您需要的内容。

请注意,环境变量可以根据其他环境变量来定义:我相信您可能会自己处理适当的扩展。

Environment variables are the amalgamation of 'puter-wide and per-user settings. A running process may modify its environment and when it spawns another process, that process inherits the environment of the process that created it.

Unless you have access to a process running on the remote machine (or can start one), there's no such thing as an 'environment': the context for it simply doesn't exist. The environment of a particular process is a function of all of the following:

  • the environment inherited from the parent process' environment (which may be running under a different user account than the child process.)
  • computer-wide environment settings.
  • any environment settings specified by the user.
  • any changes made by the process itself.

That being said, Windows keeps its environment variable settings in the registry:

  • User variables.
    HKEY_CURRENT_USER\Environment
  • System variables.
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

If you have appropriate access to the remote machine's registry, you should be able to fish out what you need.

Note that environment variables may be defined in terms of other environment variables: I believe you'll likely to take care of the proper expansion yourself.

脱离于你 2024-10-25 01:31:14

据我所知,解析 %ProgramFiles% 的唯一方法是通过注册表,因为它没有在 Win32_Environment 中公开(尽管文档另有建议)。所以这工作正常:

$key = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$serverName);
$versionKey = $key.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion');
$versionKey.GetValue('ProgramFilesDir')

但是,我似乎无法使用这种方法来取回 Program Files (x86) 文件夹 - 我在注册表中看到的密钥不会使用注册表 API“显示”。奇怪的。

当然,如果您在远程计算机上运行 Powershell Remoting,我想这会相当容易......

As far as I can tell, the only way of resolving %ProgramFiles% is via the registry, since this is not exposed in Win32_Environment (despite the documentation suggesting otherwise). So this works fine:

$key = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$serverName);
$versionKey = $key.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion');
$versionKey.GetValue('ProgramFilesDir')

However, I can't appear to use this approach to get back the Program Files (x86) folder - the key I can see in the registry doesn't 'show' using the registry API. Strange.

Of course if you were running Powershell Remoting on the remote machine, I imagine this would be fairly easy...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文