Chạy lệnh với tư cách Quản trị viên bằng PowerShell?


280

Bạn biết làm thế nào nếu bạn là người dùng quản trị của một hệ thống và bạn chỉ cần nhấp chuột phải vào một tập lệnh bó và chạy nó với tư cách Quản trị viên mà không cần nhập mật khẩu quản trị viên?

Tôi đang tự hỏi làm thế nào để làm điều này với một kịch bản PowerShell. Tôi không muốn phải nhập mật khẩu của mình; Tôi chỉ muốn bắt chước phương thức Run As Administrator .

Tất cả mọi thứ tôi đọc cho đến nay yêu cầu bạn cung cấp mật khẩu quản trị viên.


Hãy thử gsudo. Một sudo mã nguồn mở miễn phí cho các cửa sổ cho phép thực thi với tư cách quản trị viên từ dòng lệnh. Một cửa sổ bật lên UAC sẽ xuất hiện.
Gerardo Grignoli

Câu trả lời:


310

Nếu bảng điều khiển hiện tại không được nâng lên và thao tác bạn đang cố thực hiện yêu cầu các đặc quyền nâng cao thì bạn có thể bắt đầu quyền hạn với Run as administratortùy chọn:

PS> Start-Process powershell -Verb runAs

1
Đó dường như là cách duy nhất để thực hiện thành công. Tuy nhiên, cửa sổ shell được thêm vào chứng tỏ có vấn đề trong rất nhiều trường hợp. Tôi đã kết thúc việc cấu hình bất cứ thứ gì đang gọi tập lệnh để chạy với tư cách quản trị viên (ví dụ: thông qua sổ đăng ký).
Jacek Gorgoń

17
Điều này sẽ mở một giao diện điều khiển mới ở một vị trí khác. Có cách nào để chạy như quản trị viên tại thư mục làm việc hiện tại không?
Container được mã hóa

11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
Dev Anand Sadasivam


1
bạn có thể tìm tài liệu ở đây: docs.microsoft.com/en-us/powershell/module/iêu cho tập tin .exe, các động từ có thể là: Open, RunAs, RunAsUser
Kevin Xiong

114

Đây là phần bổ sung cho đề xuất của Shay Levi (chỉ cần thêm các dòng này vào đầu tập lệnh):

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

Điều này dẫn đến việc tập lệnh hiện tại được chuyển đến một quy trình quyền hạn mới trong chế độ Quản trị viên (nếu Người dùng hiện tại có quyền truy cập vào chế độ Quản trị viên và tập lệnh không được khởi chạy với tư cách Quản trị viên).


6
Điều này làm việc cho tôi:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
G. Lombard

Dễ dàng sửa đổi để chỉ ném một lỗi khi không chạy như quản trị viên. Chỉ cần lấy iftuyên bố và đặt một throwbên trong khối sau đó.
jpmc26

2
Nhận xét của @ G.Lombard có lỗi cú pháp tinh tế. Đây là những gì làm việc cho tôi:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
angensesen

Cú pháp duy nhất phù hợp với tôi là trong bài viết gốc, không phải là cú pháp của G.Lombard hay anjdreas
Nicolas Mommaerts

1
Tôi đồng ý sử dụng giá trị enum ( [Security.Principal.WindowsBuiltInRole]::Administrator)) nên được ưu tiên cho đối số chuỗi "Administrator"- Tôi gặp phải các môi trường được tăng cường bảo mật với các vai trò dựng sẵn được đổi tên
eXavier

104

Tập lệnh PowerShell tự nâng

Windows 8.1 / PowerShell 4.0 +

Một đường thẳng :)

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }

# Your script here

141
tốt, về mặt kỹ thuật, mọi thứ đều là "một dòng" nếu được định dạng như vậy, nhưng điều đó không làm cho nó thực sự là "một dòng"
người nhập cư bất hợp pháp

3
Nhược điểm: Nếu bạn nhập một người không phải là quản trị viên trong lời nhắc, bạn sẽ kết thúc trong một vòng lặp fork-exit vô tận.
Manuel Faux

3
nhưng điều này không vượt qua args
kyb

2
Để vượt qua args, tôi đã sửa đổi nó thành:if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$args`"" -Verb RunAs; exit }
ab.

2
Câu trả lời này không bảo vệ thư mục làm việc. Xem ở đây để biết: stackoverflow.com/a/57035712/2441655
Venryx 15/07/19

45

Benjamin Armstrong đã đăng một bài viết tuyệt vời về các kịch bản PowerShell tự nâng cao . Có một vài vấn đề nhỏ với mã của anh ấy; một phiên bản sửa đổi dựa trên các bản sửa lỗi được đề xuất trong bình luận bên dưới.

Về cơ bản, nó nhận được danh tính liên quan đến quy trình hiện tại, kiểm tra xem đó có phải là quản trị viên hay không và nếu không, sẽ tạo quy trình PowerShell mới với các đặc quyền của quản trị viên và chấm dứt quy trình cũ.

# Get the ID and security principal of the current user account
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID);

# Get the security principal for the administrator role
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;

# Check to see if we are currently running as an administrator
if ($myWindowsPrincipal.IsInRole($adminRole))
{
    # We are running as an administrator, so change the title and background colour to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)";
    $Host.UI.RawUI.BackgroundColor = "DarkBlue";
    Clear-Host;
}
else {
    # We are not running as an administrator, so relaunch as administrator

    # Create a new process object that starts PowerShell
    $newProcess = New-Object System.Diagnostics.ProcessStartInfo "PowerShell";

    # Specify the current script path and name as a parameter with added scope and support for scripts with spaces in it's path
    $newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"

    # Indicate that the process should be elevated
    $newProcess.Verb = "runas";

    # Start the new process
    [System.Diagnostics.Process]::Start($newProcess);

    # Exit from the current, unelevated, process
    Exit;
}

# Run your code that needs to be elevated here...

Write-Host -NoNewLine "Press any key to continue...";
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");

Tôi đã không nhận được tên tập lệnh và thông số được giải quyết đúng cách, vì vậy tôi đã kết thúc việc thực thi trong cmd.exe / c $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
xverges vào

Có bất kỳ lợi thế nào để làm điều đó như thế này thay vì Bắt đầu quá trình không? Tôi tò mò về sự khác biệt, giữa phương pháp này và các phương pháp khác được đăng ở trên và trên các chủ đề khác. Cả hai đều dựa vào .NET, nhưng phương pháp này nặng nề hơn ...
ZaxLofful

Tôi thấy các bình luận khác nhau liên quan đến liên kết trực tiếp đến bài đăng của Armstrong (câu đầu tiên của bài đăng này) cũng rất hữu ích.
BentChainRing

2
Câu trả lời này không bảo vệ thư mục làm việc. Xem ở đây để biết: stackoverflow.com/a/57035712/2441655
Venryx 15/07/19

22

Bạn có thể tạo một tệp bó ( *.bat) chạy tập lệnh powershell của bạn với các đặc quyền quản trị khi nhấp đúp. Theo cách này, bạn không cần thay đổi bất cứ điều gì trong tập lệnh powershell của mình . Để thực hiện điều này, hãy tạo một tệp bó có cùng tên và vị trí của tập lệnh powershell của bạn và sau đó đặt nội dung sau vào đó:

@echo off

set scriptFileName=%~n0
set scriptFolderPath=%~dp0
set powershellScriptFileName=%scriptFileName%.ps1

powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"%scriptFolderPath%\`\"; & \`\".\%powershellScriptFileName%\`\"`\"\" -Verb RunAs"

Đó là nó!

Đây là lời giải thích:

Giả sử tập lệnh powershell của bạn nằm trong đường dẫn C:\Temp\ScriptTest.ps1, tệp bó của bạn phải có đường dẫn C:\Temp\ScriptTest.bat. Khi ai đó thực thi tệp bó này, các bước sau sẽ xảy ra:

  1. Các cmd sẽ thực hiện lệnh

    powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
  2. Một phiên powershell mới sẽ mở và lệnh sau sẽ được thực thi:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. Một phiên quyền hạn mới khác với các đặc quyền quản trị sẽ mở trong system32thư mục và các đối số sau sẽ được truyền cho nó:

    -ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
  4. Lệnh sau sẽ được thực thi với các đặc quyền quản trị:

    cd "C:\Temp"; & ".\ScriptTest.ps1"

    Khi đường dẫn kịch bản và đối số tên được trích dẫn kép, chúng có thể chứa khoảng trắng hoặc ký tự dấu ngoặc kép đơn ( ').

  5. Thư mục hiện tại sẽ thay đổi từ system32thành C:\Tempvà tập lệnh ScriptTest.ps1sẽ được thực thi. Khi tham số -NoExitđược truyền, cửa sổ sẽ không bị đóng, ngay cả khi tập lệnh powershell của bạn ném một số ngoại lệ.


Nếu tôi làm điều này, tôi nhận được một cửa sổ bật lên hỏi tôi có cho phép PowerShell thay đổi hệ thống của mình không. Điều này làm cho nó không thể sử dụng cho tự động hóa.
John Slegers

@JohnSlegers, nếu bạn cần tự động hóa nó, bạn có trách nhiệm đảm bảo quy trình tự động được chạy với tư cách quản trị viên. Nếu bạn có thể tự động nâng quy trình không phải quản trị viên lên quy trình quản trị viên mà không có sự tương tác của người dùng, điều đó sẽ đánh bại mục đích yêu cầu một quy trình có đặc quyền quản trị viên ngay từ đầu.
meustrus

@meustrus: Là một kỹ sư phát hành , công việc của tôi liên quan đến việc tạo và duy trì các quy trình xây dựng chạy hoàn toàn tự động, theo định kỳ hoặc khi các tiêu chí nhất định được đáp ứng. Một số quy trình này cần đặc quyền của quản trị viên và yêu cầu đầu vào của người dùng làm cho quy trình không thể sử dụng được trong ngữ cảnh này. - Trong Linux, bạn có thể đạt được điều này bằng cách sử dụng sudolệnh và định cấu hình người dùng bạn sử dụng cho quy trình tự động với NOPASSWD: ALLtrong sudoerstệp .
John Slegers

1
Đây là một câu trả lời tốt hơn so với những người khác vì nó bảo vệ thư mục làm việc. Tôi kết hợp một số biến thể một dòng của cách tiếp cận này ở đây (một cho cmd / đợt, một cho các mục trình đơn ngữ cảnh Explorer và một cho các quyền hạn): stackoverflow.com/a/57033941/2441655
Venryx

17

Đây là đoạn trích tự nâng cao cho các tập lệnh Powershell bảo tồn thư mục làm việc :

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
    exit;
}

# Your script here

Việc bảo quản thư mục làm việc rất quan trọng đối với các tập lệnh thực hiện các hoạt động liên quan đến đường dẫn. Hầu như tất cả các câu trả lời khác không bảo tồn đường dẫn này, điều này có thể gây ra lỗi không mong muốn trong phần còn lại của tập lệnh.

Nếu bạn không muốn sử dụng tập lệnh / đoạn trích tự nâng cao và thay vào đó chỉ muốn một cách dễ dàng để khởi chạy tập lệnh với tư cách quản trị viên (ví dụ: từ trình đơn ngữ cảnh Explorer), hãy xem câu trả lời khác của tôi tại đây: https: // stackoverflow .com / a / 57033941/2441655


16

Sử dụng

#Requires -RunAsAdministrator

chưa được nêu, chưa. Nó dường như chỉ ở đó kể từ PowerShell 4.0.

http://technet.microsoft.com/en-us/l Library / hh847765.aspx

Khi tham số chuyển đổi này được thêm vào câu lệnh yêu cầu của bạn, nó chỉ định rằng phiên Windows PowerShell mà bạn đang chạy tập lệnh phải được bắt đầu với quyền người dùng nâng cao (Chạy với tư cách Quản trị viên).

Đối với tôi, đây có vẻ là một cách tốt để thực hiện điều này, nhưng tôi chưa chắc về trải nghiệm thực địa. Thời gian chạy PowerShell 3.0 có thể bỏ qua điều này, hoặc thậm chí tệ hơn, đưa ra lỗi.

Khi tập lệnh được chạy với tư cách là người không phải là quản trị viên, sẽ xảy ra lỗi sau:

Tập lệnh 'StackOverflow.ps1' không thể chạy được vì nó chứa câu lệnh "#requires" để chạy với tư cách Quản trị viên. Phiên Windows PowerShell hiện tại không chạy với tư cách Quản trị viên. Khởi động Windows PowerShell bằng cách sử dụng tùy chọn Run as Administrator, sau đó thử chạy lại tập lệnh.

+ CategoryInfo          : PermissionDenied: (StackOverflow.ps1:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptRequiresElevation

7
Thật không may, tất cả những gì nó làm là khiến script bị lỗi nếu shell không có đặc quyền quản trị viên. Nó không tự nâng lên.
Jacek Gorgoń 2/2/2015

PS3 xuất hiện để đưa ra một lỗi như đề xuất. Tôi nhận được Parameter RunAsAdministrator requires an argument. @akauppi Tôi không tin họ luôn suy nghĩ.
jpmc26

14

Bạn có thể dễ dàng thêm một số mục đăng ký để nhận menu ngữ cảnh "Chạy với tư cách quản trị viên" cho .ps1các tệp:

New-Item -Path "Registry::HKEY_CLASSES_ROOT\Microsoft.PowershellScript.1\Shell\runas\command" `
-Force -Name '' -Value '"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit "%1"'

(được cập nhật thành tập lệnh đơn giản hơn từ @Shay)

Về cơ bản, HKCR:\Microsoft.PowershellScript.1\Shell\runas\commandthiết lập giá trị mặc định để gọi tập lệnh bằng Powershell.


Nó không hoạt động, bạn đang tạo khóa '(mặc định)', không cập nhật giá trị khóa '(mặc định)'. Tôi đã có thể ngưng tụ mã thành một lớp lót phù hợp với tôi. Bạn có thể kiểm tra nó? Mục mới -Path "Đăng ký :: HKEY_CLASSES_ROOT \ Microsoft.PowershellScript.1 \ Shell \ runas \ lệnh" -Force -Name '' -Value '"c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -không "% 1" '
Shay Levy

@Shay Levy - Xin chào Shay, cảm ơn bạn đã cập nhật. Tôi đã cập nhật câu trả lời với nó. Nó không hoạt động. Nhưng một trong những tôi đã làm việc là tốt, mặc dù nó dài dòng. Tôi đã không thực hiện nhiều chỉnh sửa reg với Powershell, nhưng thực hiện nó với "(mặc định)" là điều mà tôi đã xem là một ví dụ. Nó không tạo ra một khóa mới (thứ giống như mặc định sẽ có) nhưng đã cập nhật khóa mặc định như mong đợi. Bạn đã thử nó hoặc chỉ đoán từ (default)phần?
manojlds

Tôi đã thử nó. Nó tạo ra một khóa '(mặc định)' dưới phím lệnh.
Shay Levy

Điều này hoạt động với tôi sau một số thay đổi nhỏ đối với giá trị đăng ký: "c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -ExecutPolicy RemoteSign -NoExit "& '% 1'"
MikeBaz - MSFT

1
Giá trị đăng ký trong câu trả lời có tất cả các loại vấn đề. Nó không thực sự chạy lệnh và nó không trích dẫn đúng tên tập lệnh (có nghĩa là nó ngắt trên các đường dẫn có khoảng trắng). Tôi đang sử dụng thành công những điều sau:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"
Kal Zekdor

10

Mã được đăng bởi Jonathan và Shay Levy không hoạt động đối với tôi.

Vui lòng tìm mã làm việc dưới đây:

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{   
#"No Administrative rights, it will display a popup window asking user for Admin rights"

$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments

break
}
#"After user clicked Yes on the popup, your file will be reopened with Admin rights"
#"Put your code here"

2
Giải pháp rất hữu ích và thực tế: chỉ cần đặt nó vào kịch bản của tôi và nó hoạt động.
CDuv

3
@Abatonime Làm thế nào về bạn chỉ ra dễ bỏ lỡ sự khác biệt vì lợi ích của độc giả của bạn thay vào đó? Thành thật mà nói, sự thay đổi đó không đáng giá hơn một bình luận về câu trả lời khác.
jpmc26

8

Bạn cần chạy lại tập lệnh với các đặc quyền quản trị và kiểm tra xem tập lệnh đã được khởi chạy ở chế độ đó chưa. Dưới đây tôi đã viết một tập lệnh có hai chức năng: DoElevatedOperationsDoSt ChuẩnOperations . Bạn nên đặt mã yêu cầu quyền quản trị viên vào mã đầu tiên và thao tác chuẩn vào mã thứ hai. Biến IsRunAsAdmin được sử dụng để xác định chế độ quản trị viên.

Mã của tôi là một trích xuất đơn giản từ tập lệnh Microsoft được tạo tự động khi bạn tạo gói ứng dụng cho các ứng dụng Windows Store.

param(
    [switch]$IsRunAsAdmin = $false
)

# Get our script path
$ScriptPath = (Get-Variable MyInvocation).Value.MyCommand.Path

#
# Launches an elevated process running the current script to perform tasks
# that require administrative privileges.  This function waits until the
# elevated process terminates.
#
function LaunchElevated
{
    # Set up command line arguments to the elevated process
    $RelaunchArgs = '-ExecutionPolicy Unrestricted -file "' + $ScriptPath + '" -IsRunAsAdmin'

    # Launch the process and wait for it to finish
    try
    {
        $AdminProcess = Start-Process "$PsHome\PowerShell.exe" -Verb RunAs -ArgumentList $RelaunchArgs -PassThru
    }
    catch
    {
        $Error[0] # Dump details about the last error
        exit 1
    }

    # Wait until the elevated process terminates
    while (!($AdminProcess.HasExited))
    {
        Start-Sleep -Seconds 2
    }
}

function DoElevatedOperations
{
    Write-Host "Do elevated operations"
}

function DoStandardOperations
{
    Write-Host "Do standard operations"

    LaunchElevated
}


#
# Main script entry point
#

if ($IsRunAsAdmin)
{
    DoElevatedOperations
}
else
{
    DoStandardOperations
}

7

Thêm 2 xu của tôi. Phiên bản đơn giản của tôi dựa trên phiên net hoạt động mọi lúc cho đến nay trong Windows 7 / Windows 10. Tại sao lại quá phức tạp?

if (!(net session)) {$path =  "& '" + $myinvocation.mycommand.definition + "'" ; Start-Process powershell -Verb runAs -ArgumentList $path ; exit}

chỉ cần thêm vào đầu tập lệnh và nó sẽ chạy với tư cách quản trị viên.


1
Có cách nào để gửi tin nhắn cho người dùng sau khi "Truy cập bị từ chối" được hiển thị không?
ycomp

... Hoặc để tránh tin nhắn này
Günter Zöchbauer

1
@ GünterZöchbauer if (!(net session 2>&1 | Out-Null)) { ... @ycomp ... } else { echo "your message" }.
Matthieu

gặp lỗi vì điều này,cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
user2305193

1
@ user2305193 Set-ExecutionPolicy -ExecutionPolicy <PolicyName>, Bạn có thể đặt thành bypass Nhưng bypasscó thể nguy hiểm. Đặt nó thànhAllSigned
AliFurkan

5

Hành vi này là do thiết kế. Có nhiều lớp bảo mật vì Microsoft thực sự không muốn các tệp .ps1 trở thành virus email mới nhất. Một số người thấy điều này là trái ngược với khái niệm tự động hóa nhiệm vụ, đó là công bằng. Mô hình bảo mật Vista + là để "tự động hóa" mọi thứ, do đó làm cho người dùng không sao.

Tuy nhiên, tôi nghi ngờ nếu bạn khởi chạy powershell khi nó được nâng lên, nó sẽ có thể chạy các tệp bó mà không yêu cầu lại mật khẩu cho đến khi bạn đóng powershell.


5

Tất nhiên, bạn cũng có thể buộc ứng dụng mở với tư cách quản trị viên, nếu bạn có tài khoản quản trị viên.

nhập mô tả hình ảnh ở đây

Xác định vị trí tệp, nhấp chuột phải> thuộc tính> Phím tắt> Nâng cao và kiểm tra Chạy với tư cách Quản trị viên

Sau đó bấm OK.


1
Làm thế nào để bạn kịch bản này?
Dieter

4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShelllà nơi chứa các phím tắt của PowerShell. Nó vẫn đi đến một địa điểm khác để gọi 'exe' ( %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe) thực tế .

Vì PowerShell là hồ sơ người dùng điều khiển khi có liên quan đến quyền; nếu tên người dùng / hồ sơ của bạn có quyền làm điều gì đó thì trong hồ sơ đó, trong PowerShell, bạn thường có thể làm điều đó. Điều đó đang được nói, sẽ có nghĩa là bạn sẽ thay đổi phím tắt nằm trong hồ sơ người dùng của bạn, ví dụ , C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell.

Nhấp chuột phải và nhấp vào thuộc tính. Nhấp vào nút "Nâng cao" trong tab "Phím tắt" nằm ngay bên dưới trường văn bản "Nhận xét" bên cạnh hai nút khác, "Vị trí tệp mở" và "Biểu tượng thay đổi", tương ứng.

Chọn hộp kiểm có nội dung "Chạy với tư cách Quản trị viên". Bấm OK, sau đó ApplyOK. Một lần nữa, nhấp chuột phải vào biểu tượng có nhãn 'Windows PowerShell' nằm trong C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellvà chọn "Ghim vào Menu / Thanh tác vụ".

Bây giờ bất cứ khi nào bạn nhấp vào biểu tượng đó, nó sẽ gọi UAC để leo thang. Sau khi chọn 'CÓ', bạn sẽ thấy bảng điều khiển PowerShell mở và nó sẽ được gắn nhãn "Quản trị viên" trên đầu màn hình.

Để tiến thêm một bước nữa ... bạn có thể nhấp chuột phải vào cùng một phím tắt biểu tượng trong vị trí hồ sơ Windows PowerShell của bạn và gán một phím tắt sẽ thực hiện chính xác như khi bạn nhấp vào biểu tượng được thêm gần đây. Vì vậy, nơi nó nói "Phím tắt" đặt trong tổ hợp phím / nút bàn phím như: Ctrl+ Alt+ P P(đối với PowerShell) . Nhấp ApplyOK.

Bây giờ, tất cả những gì bạn phải làm là nhấn tổ hợp nút mà bạn đã chỉ định và bạn sẽ thấy UAC được gọi và sau khi bạn chọn 'CÓ', bạn sẽ thấy bảng điều khiển PowerShell xuất hiện và "Quản trị viên" hiển thị trên thanh tiêu đề.


Anh bạn :) Từ khóa trong câu hỏi của OP là kịch bản !! Không phải một số giải pháp nhấp chuột UI.
Christian

3

Tôi đã tìm ra cách để làm điều này ...

Tạo một tệp bó để mở tập lệnh của bạn:

@echo off
START "" "C:\Scripts\ScriptName.ps1"

Sau đó, tạo một lối tắt, trên màn hình của bạn nói (nhấp chuột phải vào Mới -> Phím tắt ).

Sau đó dán cái này vào vị trí:

C:\Windows\System32\runas.exe /savecred /user:*DOMAIN*\*ADMIN USERNAME* C:\Scripts\BatchFileName.bat

Khi mở lần đầu tiên, bạn sẽ phải nhập mật khẩu của mình một lần. Điều này sau đó sẽ lưu nó trong trình quản lý thông tin Windows.

Sau đó, bạn sẽ có thể chạy với tư cách quản trị viên mà không cần phải nhập tên người dùng hoặc mật khẩu của quản trị viên.


/ savecred không an toàn!
Chuyến đi của Nathan

Đây là giải pháp duy nhất không sử dụng dấu nhắc độ cao đồ họa có thể không truy cập được trên một phiên từ xa.
DustWolf

3

Vấn đề với câu trả lời của @pgk@Andrew Odri là khi bạn có các tham số tập lệnh, đặc biệt khi chúng là bắt buộc. Bạn có thể giải quyết vấn đề này bằng cách sử dụng phương pháp sau:

  1. Người dùng nhấp chuột phải vào tệp .ps1 và chọn 'Chạy với PowerShell': hỏi anh ta về các tham số thông qua các hộp nhập (đây là một tùy chọn tốt hơn nhiều so với sử dụng thuộc tính tham số HelpMessage );
  2. Người dùng thực thi tập lệnh thông qua bàn điều khiển: cho phép anh ta vượt qua các tham số mong muốn và để giao diện điều khiển buộc anh ta phải thông báo cho những người bắt buộc.

Đây là mã như thế nào nếu tập lệnh có các tham số bắt buộc ComputerNamePort :

[CmdletBinding(DefaultParametersetName='RunWithPowerShellContextMenu')]
param (
    [parameter(ParameterSetName='CallFromCommandLine')]
    [switch] $CallFromCommandLine,

    [parameter(Mandatory=$false, ParameterSetName='RunWithPowerShellContextMenu')]
    [parameter(Mandatory=$true, ParameterSetName='CallFromCommandLine')]
    [string] $ComputerName,

    [parameter(Mandatory=$false, ParameterSetName='RunWithPowerShellContextMenu')]
    [parameter(Mandatory=$true, ParameterSetName='CallFromCommandLine')]
    [UInt16] $Port
)

function Assert-AdministrativePrivileges([bool] $CalledFromRunWithPowerShellMenu)
{
    $isAdministrator = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

    if ($isAdministrator)
    {
        if (!$CalledFromRunWithPowerShellMenu -and !$CallFromCommandLine)
        {
            # Must call itself asking for obligatory parameters
            & "$PSCommandPath" @script:PSBoundParameters -CallFromCommandLine
            Exit
        }
    }
    else
    {
        if (!$CalledFromRunWithPowerShellMenu -and !$CallFromCommandLine)
        {
            $serializedParams = [Management.Automation.PSSerializer]::Serialize($script:PSBoundParameters)

            $scriptStr = @"
                `$serializedParams = '$($serializedParams -replace "'", "''")'

                `$params = [Management.Automation.PSSerializer]::Deserialize(`$serializedParams)

                & "$PSCommandPath" @params -CallFromCommandLine
"@

            $scriptBytes = [System.Text.Encoding]::Unicode.GetBytes($scriptStr)
            $encodedCommand = [Convert]::ToBase64String($scriptBytes)

            # If this script is called from another one, the execution flow must wait for this script to finish.
            Start-Process -FilePath 'powershell' -ArgumentList "-ExecutionPolicy Bypass -NoProfile -EncodedCommand $encodedCommand" -Verb 'RunAs' -Wait
        }
        else
        {
            # When you use the "Run with PowerShell" feature, the Windows PowerShell console window appears only briefly.
            # The NoExit option makes the window stay visible, so the user can see the script result.
            Start-Process -FilePath 'powershell' -ArgumentList "-ExecutionPolicy Bypass -NoProfile -NoExit -File ""$PSCommandPath""" -Verb 'RunAs'
        }

        Exit
    }
}

function Get-UserParameters()
{
    [string] $script:ComputerName = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a computer name:', 'Testing Network Connection')

    if ($script:ComputerName -eq '')
    {
        throw 'The computer name is required.'
    }

    [string] $inputPort = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a TCP port:', 'Testing Network Connection')

    if ($inputPort -ne '')
    {
        if (-not [UInt16]::TryParse($inputPort, [ref]$script:Port))
        {
            throw "The value '$inputPort' is invalid for a port number."
        }
    }
    else
    {
        throw 'The TCP port is required.'
    }
}

# $MyInvocation.Line is empty in the second script execution, when a new powershell session
# is started for this script via Start-Process with the -File option.
$calledFromRunWithPowerShellMenu = $MyInvocation.Line -eq '' -or $MyInvocation.Line.StartsWith('if((Get-ExecutionPolicy')

Assert-AdministrativePrivileges $calledFromRunWithPowerShellMenu

# Necessary for InputBox
[System.Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') | Out-Null

if ($calledFromRunWithPowerShellMenu)
{
    Get-UserParameters
}

# ... script code
Test-NetConnection -ComputerName $ComputerName -Port $Port

3

Một số câu trả lời ở đây rất gần, nhưng công việc nhiều hơn mức cần thiết.

Tạo lối tắt đến tập lệnh của bạn và định cấu hình nó thành "Chạy với tư cách Quản trị viên":

  • Tạo lối tắt.
  • Nhấp chuột phải và mở Properties...
  • Chỉnh sửa Targettừ <script-path>thànhpowershell <script-path>
  • Nhấp Advanced...và bậtRun as administrator

2

Một giải pháp đơn giản hơn là bạn cũng có thể nhấp chuột phải vào "C: \ Windows \ System32 \ cmd.exe" và chọn "Chạy với tư cách quản trị viên", sau đó bạn có thể chạy bất kỳ ứng dụng nào với tư cách quản trị viên mà không cần cung cấp bất kỳ mật khẩu nào.


2

Tôi đang sử dụng giải pháp dưới đây. Nó xử lý stdout / stderr thông qua tính năng sao chép và chuyển mã thoát chính xác cho tiến trình cha. Bạn cần điều chỉnh đường dẫn bản ghi / tên tệp.

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{ 
  echo "* Respawning PowerShell child process with elevated privileges"
  $pinfo = New-Object System.Diagnostics.ProcessStartInfo
  $pinfo.FileName = "powershell"
  $pinfo.Arguments = "& '" + $myinvocation.mycommand.definition + "'"
  $pinfo.Verb = "RunAs"
  $pinfo.RedirectStandardError = $false
  $pinfo.RedirectStandardOutput = $false
  $pinfo.UseShellExecute = $true
  $p = New-Object System.Diagnostics.Process
  $p.StartInfo = $pinfo
  $p.Start() | Out-Null
  $p.WaitForExit()
  echo "* Child process finished"
  type "C:/jenkins/transcript.txt"
  Remove-Item "C:/jenkins/transcript.txt"
  Exit $p.ExitCode
} Else {
  echo "Child process starting with admin privileges"
  Start-Transcript -Path "C:/jenkins/transcript.txt"
}

# Rest of your script goes here, it will be executed with elevated privileges

Điều này làm mất tất cả các đối số gọi
Guillermo Prandi

2

Dưới đây là cách chạy lệnh powershell nâng cao và thu thập biểu mẫu đầu ra của nó trong tệp bó windows trong một lệnh duy nhất (nghĩa là không viết tập lệnh powershell ps1).

powershell -Command 'Start-Process powershell -ArgumentList "-Command (Get-Process postgres | Select-Object Path | Select-Object -Index 0).Path | Out-File -encoding ASCII $env:TEMP\camp-postgres.tmp" -Verb RunAs'

Ở trên bạn thấy tôi lần đầu tiên khởi chạy một powershell với dấu nhắc nâng cao và sau đó yêu cầu khởi chạy một powershell khác (shell phụ) để chạy lệnh.


1

Trên đầu câu trả lời của Shay Levy, hãy làm theo thiết lập bên dưới (chỉ một lần)

  1. Bắt đầu một PowerShell với quyền Quản trị viên.
  2. Thực hiện theo câu hỏi về Stack Overflow PowerShell nói rằng việc thực thi các tập lệnh bị vô hiệu hóa trên hệ thống này..
  3. PATHVí dụ, đặt tệp .ps1 của bạn vào bất kỳ thư mục nào. Thư mục Windows \ System32

Sau khi thiết lập:

  1. Nhấn Win+R
  2. Gọi powershell Start-Process powershell -Verb runAs <ps1_file>

Bây giờ bạn có thể chạy mọi thứ chỉ trong một dòng lệnh. Các hoạt động trên trên Windows 8 Basic 64-bit.


1

Cách đáng tin cậy nhất mà tôi đã tìm thấy là bọc nó trong tệp .bat tự nâng cao:

@echo off
NET SESSION 1>NUL 2>NUL
IF %ERRORLEVEL% EQU 0 GOTO ADMINTASKS
CD %~dp0
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 0); close();"
EXIT

:ADMINTASKS

powershell -file "c:\users\joecoder\scripts\admin_tasks.ps1"

EXIT

.Bat kiểm tra nếu bạn đã là quản trị viên và khởi chạy lại tập lệnh với tư cách Quản trị viên nếu cần. Nó cũng ngăn các cửa sổ "cmd" bên ngoài mở ra với tham số thứ 4 ShellExecute()được đặt thành 0.


Câu trả lời tốt, nhưng tôi đã thử và không hoạt động (và thoát khỏi dòng lệnh mà tôi gọi nó). Tôi đã sửa theo cách này: Tôi đã thay đổi cái đầu tiên EXITthành a GOTO :EOFvà xóa cái thứ hai. Ngoài ra, cd %~dp0nên được cd /d %~dp0đặt AND lệnh đầu tiên sau @echo off. Bằng cách này, bạn không cần đường dẫn tuyệt đối của một .ps1trong hai, chỉ cần đặt nó vào cùng thư mục đó .bat. Nếu bạn cần xem kết quả, hãy thay đổi tham số thứ 4 thành 1.
cdlvcdlv

Bạn đang chạy phiên bản O / S nào?
Joe Coder

Windows 7 SP1 Cuối cùng. Tôi có hệ thống trong C: nhưng cũng có dữ liệu và ứng dụng di động trong D: chủ yếu (và một số ổ đĩa khác). Nhân tiện ... nếu chương trình / tập lệnh sử dụng tham số thì sao? Điều gì sẽ là mshtalệnh?
cdlvcdlv

Tôi nghĩ rằng bạn có thể đã sai trong thử nghiệm của mình, bởi vì kịch bản hoạt động tốt. Nhân tiện, nó được thiết kế để thoát khỏi cmdquá trình gọi để không "sửa" nó, nhưng tôi rất vui vì bạn có thể sửa đổi nó theo nhu cầu của mình.
Joe Coder

Ok nếu bạn muốn thoát cmd(tôi đã không). Nhưng liên quan đến các thay đổi khác, tôi nghĩ là các bản sửa lỗi vì phiên bản của tôi sẽ hoạt động cho cả hai chúng tôi trong khi phiên bản của bạn không dành cho tôi, tức là chung hơn của tôi (giải quyết tình huống của các ổ đĩa khác nhau). Dù sao, một cách tiếp cận rất thông minh.
cdlvcdlv

0

Tôi chưa từng thấy cách làm của riêng mình trước đây, vì vậy, hãy thử nó. Đó là cách dễ dàng hơn để làm theo và có dấu chân nhỏ hơn nhiều:

if([bool]([Security.Principal.WindowsIdentity]::GetCurrent()).Groups -notcontains "S-1-5-32-544") {
    Start Powershell -ArgumentList "& '$MyInvocation.MyCommand.Path'" -Verb runas
    }

Rất đơn giản, nếu phiên Powershell hiện tại được gọi với các đặc quyền của quản trị viên, SID nổi tiếng của Nhóm quản trị viên sẽ hiển thị trong Nhóm khi bạn lấy danh tính hiện tại. Ngay cả khi tài khoản là thành viên của nhóm đó, SID sẽ không hiển thị trừ khi quy trình được gọi với thông tin đăng nhập nâng cao.

Gần như tất cả các câu trả lời này là một biến thể của phương pháp cực kỳ phổ biến của Microsoft Ben Armstrong về cách thực hiện nó trong khi không thực sự nắm bắt những gì nó thực sự đang làm và cách khác để mô phỏng cùng một thói quen.


0

Để nối đầu ra của lệnh vào tên tệp văn bản bao gồm ngày hiện tại, bạn có thể làm một cái gì đó như thế này:

$winupdfile = 'Windows-Update-' + $(get-date -f MM-dd-yyyy) + '.txt'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -Command `"Get-WUInstall -AcceptAll | Out-File $env:USERPROFILE\$winupdfile -Append`"" -Verb RunAs; exit } else { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -Command `"Get-WUInstall -AcceptAll | Out-File $env:USERPROFILE\$winupdfile -Append`""; exit }

0

Đây là một sự làm rõ ...

Thông tin xác thực RUNAS / SAVECRED "không an toàn", đã thử và nó thêm danh tính và mật khẩu quản trị viên vào bộ đệm thông tin xác thực và có thể được sử dụng ở nơi khác OOPS!. Nếu bạn đã làm điều này, tôi khuyên bạn nên kiểm tra và loại bỏ mục.

Xem lại chương trình hoặc mã của bạn vì chính sách của Microsoft là bạn không thể có mã người dùng và quản trị viên hỗn hợp trong cùng một mã blob mà không có UAC (điểm vào) để thực thi chương trình với tư cách quản trị viên. Đây sẽ là sudo (điều tương tự) trên Linux.

UAC có 3 loại, dont'see, dấu nhắc hoặc điểm nhập được tạo trong tệp kê khai của chương trình. Nó không nâng cao chương trình nên nếu không có UAC và nó cần quản trị viên thì nó sẽ thất bại. Mặc dù UAC là một yêu cầu quản trị viên tốt, nhưng nó ngăn chặn việc thực thi mã mà không cần xác thực và ngăn kịch bản mã hỗn hợp thực thi ở cấp độ người dùng.


Đây phải là một nhận xét, nó không phải là một giải pháp cho câu hỏi (chỉ là cách diễn đàn hoạt động; nội dung của bạn hữu ích, nhưng không phải là một giải pháp).
bgmCoder

-2

Hóa ra nó quá dễ dàng. Tất cả bạn phải làm là chạy một cmd là quản trị viên. Sau đó gõ explorer.exevà nhấn enter. Điều đó mở ra Windows Explorer . Bây giờ, nhấp chuột phải vào tập lệnh PowerShell mà bạn muốn chạy, chọn "chạy với PowerShell" sẽ khởi chạy nó trong PowerShell ở chế độ quản trị viên.

Nó có thể yêu cầu bạn kích hoạt chính sách để chạy, nhập Y và nhấn enter. Bây giờ tập lệnh sẽ chạy trong PowerShell với tư cách quản trị viên. Trong trường hợp nó chạy toàn bộ màu đỏ, điều đó có nghĩa là chính sách của bạn chưa ảnh hưởng. Sau đó thử lại và nó sẽ hoạt động tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.