Powershell以管理员身份

微软

成员
已加入
2020年1月26日
留言内容
5
编程经验
Beginner
你好,

我在转圈。我有一个在安装了应用程序的本地计算机上组装Powershell脚本(UNC目录中的Get-ChildItems | Remove-Item)的应用程序。
应用程序成功地组装了.ps1文件,当我以管理员身份打开ps时,该文件可以完美运行。

但是,我找不到任何办法以管理员身份打开Powershell.Create()来运行脚本。现在它什么也没做...

C#:
 private void Execute_Script_CMD(int _i, string _cmd)
        {
            _i = _i - 1;
            jobs.Add(false);

            WSManConnectionInfo _conInfo = new WSManConnectionInfo();
            _conInfo.ComputerName = serverHost;
            Runspace _psRun = RunspaceFactory.CreateRunspace(_conInfo);
            using (PowerShell _pscon = PowerShell.Create())
            {
                _psRun.Open();
                _pscon.Runspace = _psRun;
                
                var re = _pscon.AddScript(@"'" + _cmd + @"'");
                var results = re.Invoke();


                _pscon.Runspace.Close();
                _pscon.Dispose();
            }
            


            /*
            RunspaceMode rsM = RunspaceMode.NewRunspace;
            PowerShell _pscon = PowerShell.Create(rsM);
            _pscon.AddScript("Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser -Force");
            _pscon.AddScript(@"'" + _cmd + @"'");
            _pscon.Invoke();
            _pscon.Runspace.Close();
            */
            jobs[_i] = true;
        }

上面的代码有两个版本。最初,我只是从创建控制台,添加脚本和执行调用开始...现在,从尝试每个人的建议开始,到处都是这些东西,但是没有任何效果...

我还将这一行添加到我的应用清单中,以便该应用程序本身以管理员身份启动:

HTML:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

任何有关如何执行此操作的帮助将不胜感激。

干杯,
史蒂夫
 

微软

成员
已加入
2020年1月26日
留言内容
5
编程经验
Beginner
Start-Process powershell -Verb runAs
另请参阅: 启动过程(Microsoft.PowerShell.Management) 用于在给定的工作目录上执行

我很困惑...您要我使用c#启动Powershell,然后再次启动Powershell并传递命令吗?那是唯一有效的解决方法吗?我如何从命令中得到回报,说它已经完成了第二个模块中的脚本处理?
 

跳伞者

工作人员
已加入
2019年4月6日
留言内容
2,609
地点
弗吉尼亚州切萨皮克
编程经验
10+
这很奇怪……首先验证您的脚本确实以管理员身份运行。

用我的代码看起来像这样:
C#:
using System;
using System.Management.Automation;

namespace TestPSHost
{
    class Program
    {
        static void Main(string[] args)
        {
            string script =
@"$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)";

            var ps = PowerShell.Create();
            ps.AddScript(script);
            var results = ps.Invoke();
            foreach (var result in results)
                Console.WriteLine(result);
        }
    }
}

如果我的app.manifest有"asInvoker"然后我得到的输出"False" (because I don't always run as admin). 如果我的app.manifest有"requireAdministrator",那么我得到的输出"True"。 (此外,如果要在Visual Studio中进行测试,则需要以管理员身份运行VS来调试app.manifest是否具有"requireAdministrator".)

通常,Windows的工作方式是,如果父应用程序以管理员身份运行,则所有派生应用程序也将以管理员身份运行。因此,如果您的应用程序确实以管理员身份运行,那么您执行的任何powershell脚本也应以管理员身份运行。
 

微软

成员
已加入
2020年1月26日
留言内容
5
编程经验
Beginner
这很奇怪……首先验证您的脚本确实以管理员身份运行。

用我的代码看起来像这样:
C#:
using System;
using System.Management.Automation;

namespace TestPSHost
{
    class Program
    {
        static void Main(string[] args)
        {
            string script =
@"$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)";

            var ps = PowerShell.Create();
            ps.AddScript(script);
            var results = ps.Invoke();
            foreach (var result in results)
                Console.WriteLine(result);
        }
    }
}

如果我的app.manifest有"asInvoker"然后我得到的输出"False" (because I don't always run as admin). 如果我的app.manifest有"requireAdministrator",那么我得到的输出"True"。 (此外,如果要在Visual Studio中进行测试,则需要以管理员身份运行VS来调试app.manifest是否具有"requireAdministrator".)

通常,Windows的工作方式是,如果父应用程序以管理员身份运行,则所有派生应用程序也将以管理员身份运行。因此,如果您的应用程序确实以管理员身份运行,那么您执行的任何powershell脚本也应以管理员身份运行。

是的,因此我以应用程序的Admin身份运行VS,App Manifest以管理员身份运行。我什至还构建并发布了该应用程序以在安装时进行测试,但实际上没有一个脚本可以执行。
以admin身份在PS ISE中打开脚本文件,运行完全相同的脚本文件,并且执行效果完美。

虽然我最初有一个类似的脚本块,但实际上不必使用调用结果。如果控制台存在某种执行问题,而无法访问脚本的存储位置(用户使用localappdata),可以在Vs中获取该脚本以输出到消息框或其他内容吗?
 

跳伞者

工作人员
已加入
2019年4月6日
留言内容
2,609
地点
弗吉尼亚州切萨皮克
编程经验
10+
Trim down the script to only do a simple Start-Transcript and Stop-Transcript and nothing else. Make sure that the script actually executes.

Out of curiousity if all you are doing in your script is Get-ChildItem | Remove-Item why even use PowerShell. Just do something like:
C#:
foreach(var file in Directory.EnumerateFiles( ... ))
    File.Delete(file);
 

微软

成员
已加入
2020年1月26日
留言内容
5
编程经验
Beginner
我想我已经知道了。我目前不在此方面进行工作,但这可能与管理方面无关,可能是因为脚本路径包含空格。
我之前在脚本周围添加了‘,因为它试图执行之前的第一个空格...
现在,我只是在猜测,但是我假设将脚本路径作为字符串粘贴到Powershell中,将不会导致任何事情发生(这正是我的问题所在)

我正在考虑执行以下操作来绕过它;


C#:
ps.addScript(
    @"Set-location '" + scriptPathDir + @"';
    .\script.ps1;"
);
 

微软

成员
已加入
2020年1月26日
留言内容
5
编程经验
Beginner
Trim down the script to only do a simple Start-Transcript and Stop-Transcript and nothing else. Make sure that the script actually executes.

Out of curiousity if all you are doing in your script is Get-ChildItem | Remove-Item why even use PowerShell. Just do something like:
C#:
foreach(var file in Directory.EnumerateFiles( ... ))
    File.Delete(file);

是的,我基本上简化了它,因为它基本上是在企业平台上清理Citrix配置文件的工具。
在删除目录之前,它已包含各种过滤器,检查,日志记录等。
 

跳伞者

工作人员
已加入
2019年4月6日
留言内容
2,609
地点
弗吉尼亚州切萨皮克
编程经验
10+
这:
C#:
_pscon.AddScript(@"'" + _cmd + @"'");
似乎不必要地复杂。不需要使用“ @”来保护单引号。

可以简化为:
C#:
_pscon.AddScript(string.Format("'{0}'", _cmd));
或者
C#:
_pscon.AddScript($"'{_cmd}'");
或者
C#:
_pscon.AddScript("'" + _cmd + "'");

无论如何,模糊地回想起某种问题,例如执行存在于空格路径中的脚本。我想我通过使用类似的方法解决了它:
C#:
& 'C:\some\path with spaces\script.ps1'
 
最佳 底部