PowerShell: व्यवस्थापक के रूप में कमांड चला रहा है



Answers

यहां शै लेवी के सुझाव के अलावा एक जोड़ा है (बस एक स्क्रिप्ट की शुरुआत में इन पंक्तियों को जोड़ें):

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
}

इसके परिणामस्वरूप मौजूदा स्क्रिप्ट को व्यवस्थापक मोड में एक नई पावरहेल प्रक्रिया में पारित किया जा रहा है (यदि वर्तमान उपयोगकर्ता के पास व्यवस्थापक मोड तक पहुंच है और स्क्रिप्ट प्रशासक के रूप में लॉन्च नहीं है)।

Question

आप जानते हैं कि यदि आप किसी सिस्टम के व्यवस्थापकीय उपयोगकर्ता हैं और आप बस बैच स्क्रिप्ट कहें, और व्यवस्थापक पासवर्ड दर्ज किए बिना इसे प्रशासक के रूप में चलाएं?

मैं सोच रहा हूं कि PowerShell स्क्रिप्ट के साथ ऐसा कैसे करें। मैं अपना पासवर्ड दर्ज नहीं करना चाहता; मैं सिर्फ राइट-क्लिक रन एडमिनिस्ट्रेटर विधि की नकल करना चाहता हूं।

अब तक जो कुछ भी मैंने पढ़ा है, वह आपको प्रशासक पासवर्ड की आपूर्ति करने की आवश्यकता है।




मुझे मिला सबसे विश्वसनीय तरीका यह है कि इसे एक स्व-एलिवेटिंग .bat फ़ाइल में लपेटें:

@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 जांचता है कि क्या आप पहले से ही व्यवस्थापक हैं और यदि आवश्यक हो तो व्यवस्थापक के रूप में स्क्रिप्ट को फिर से लॉन्च करता है। यह बाहरी "cmd" विंडो को ShellExecute() के 4 वें पैरामीटर के साथ खोलने से रोकता है।




आप एप्लिकेशन को व्यवस्थापक के रूप में खोलने के लिए भी मजबूर कर सकते हैं। यदि आपके पास निश्चित रूप से एक प्रशासक खाता है।

फ़ाइल का पता लगाएँ, राइट क्लिक> गुण> शॉर्टकट> उन्नत और व्यवस्थापक के रूप में चलाएं चेक करें

फिर ठीक क्लिक करें।




यह पता चला कि यह बहुत आसान था। आपको बस इतना करना है कि व्यवस्थापक के रूप में एक cmd चलाएं। फिर explorer.exe टाइप करें और एंटर दबाएं। यह Windows Explorer खुलता है। अब अपनी पावरशेल स्क्रिप्ट पर राइट क्लिक करें जिसे आप चलाने के लिए चाहते हैं, "PowerShell के साथ चलाएं" चुनें जो इसे PowerShell में व्यवस्थापक मोड में लॉन्च करेगा।

यह आपको नीति चलाने के लिए सक्षम करने के लिए कह सकता है, वाई टाइप करें और एंटर दबाएं। अब स्क्रिप्ट व्यवस्थापक के रूप में PowerShell में चलाएगी। यदि यह सब लाल हो जाता है, तो इसका मतलब है कि आपकी नीति अभी तक प्रभावित नहीं हुई है। फिर पुन: प्रयास करें और इसे ठीक काम करना चाहिए।




मैं नीचे दिए गए समाधान का उपयोग कर रहा हूं। यह ट्रांसक्रिप्ट सुविधा के माध्यम से stdout / stderr को संभालता है और पैरेंट प्रक्रिया के लिए सही ढंग से निकास कोड पास करता है। आपको ट्रांसक्रिप्ट पथ / फ़ाइल नाम समायोजित करने की आवश्यकता है।

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



एक और आसान समाधान यह है कि आप "सी: \ विंडोज \ System32 \ cmd.exe" पर भी राइट क्लिक कर सकते हैं और "व्यवस्थापक के रूप में चलाएं" चुनें, फिर आप कोई भी पासवर्ड प्रदान किए बिना व्यवस्थापक के रूप में किसी ऐप को चला सकते हैं।




@pgk और @Andrew Odri के उत्तरों के साथ समस्या तब होती है जब आपके पास स्क्रिप्ट पैरामीटर होते हैं, खासकर जब वे अनिवार्य होते हैं। आप निम्न दृष्टिकोण का उपयोग करके इस समस्या को हल कर सकते हैं:

  1. उपयोगकर्ता .ps1 फ़ाइल पर राइट-क्लिक करता है और 'PowerShell के साथ चलाएं' का चयन करता है: उसे इनपुट बॉक्स के माध्यम से पैरामीटर के लिए पूछें (यह HelpMessage पैरामीटर विशेषता का उपयोग करने से यह एक बेहतर विकल्प है);
  2. उपयोगकर्ता कंसोल के माध्यम से स्क्रिप्ट निष्पादित करता है: उसे वांछित पैरामीटर पास करने दें और कंसोल को अनिवार्य लोगों को सूचित करने के लिए मजबूर करें।

यहां बताया गया है कि यदि स्क्रिप्ट में कंप्यूटर नाम और पोर्ट अनिवार्य पैरामीटर था तो कोड कैसे होगा:

[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



बेंजामिन आर्मस्ट्रांग ने स्वयं को पावरशेल स्क्रिप्ट को बढ़ाने के बारे में एक उत्कृष्ट लेख पोस्ट किया। उसके कोड के साथ कुछ मामूली समस्या; टिप्पणी में सुझाए गए फिक्सेस के आधार पर एक संशोधित संस्करण नीचे दिया गया है।

असल में यह वर्तमान प्रक्रिया से जुड़ी पहचान प्राप्त करता है, यह जांचता है कि यह एक प्रशासक है, और यदि यह नहीं है, तो व्यवस्थापक विशेषाधिकारों के साथ एक नई पावरशेल प्रक्रिया बनाता है और पुरानी प्रक्रिया को समाप्त करता है।

# 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");



का उपयोग करते हुए

#Requires -RunAsAdministrator

अभी तक नहीं बताया गया है। ऐसा लगता है कि केवल PowerShell 4.0 के बाद से ही ऐसा लगता है।

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

जब यह स्विच पैरामीटर आपके आवश्यक कथन में जोड़ा जाता है, तो यह निर्दिष्ट करता है कि Windows PowerShell सत्र जिसमें आप स्क्रिप्ट चला रहे हैं, को उन्नत उपयोगकर्ता अधिकारों (व्यवस्थापक के रूप में चलाएं) के साथ प्रारंभ किया जाना चाहिए।

मेरे लिए, यह इस बारे में जाने के लिए एक अच्छा तरीका प्रतीत होता है, लेकिन मुझे अभी तक क्षेत्र के अनुभव का यकीन नहीं है। PowerShell 3.0 रनटाइम शायद इसे अनदेखा करते हैं, या इससे भी बदतर, त्रुटि देते हैं।

जब स्क्रिप्ट गैर-व्यवस्थापक के रूप में चलायी जाती है, तो निम्न त्रुटि दी जाती है:

स्क्रिप्ट '.ps1' को चलाया नहीं जा सकता क्योंकि इसमें व्यवस्थापक के रूप में चलाने के लिए "#requires" कथन शामिल है। वर्तमान Windows PowerShell सत्र व्यवस्थापक के रूप में नहीं चल रहा है। व्यवस्थापक के रूप में रन का उपयोग करके Windows PowerShell प्रारंभ करें, और उसके बाद स्क्रिप्ट को फिर से चलाने का प्रयास करें।

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



C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell वह जगह है जहां C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell का शॉर्टकट रहता है। यह वास्तविक 'exe' ( %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe ) का आह्वान करने के लिए अभी भी एक अलग स्थान पर जाता है।

चूंकि पॉवरशेल उपयोगकर्ता प्रोफ़ाइल को अनुमति देता है जब अनुमतियां संबंधित होती हैं; यदि आपके उपयोगकर्ता नाम / प्रोफाइल में कुछ करने की अनुमति है तो उस प्रोफ़ाइल के तहत, PowerShell में आप आमतौर पर इसे भी करने में सक्षम होंगे। ऐसा कहा जा रहा है, यह समझ में आता है कि आप अपने उपयोगकर्ता प्रोफ़ाइल के अंतर्गत स्थित शॉर्टकट को बदल देंगे, उदाहरण के लिए, C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell

राइट-क्लिक करें और गुण क्लिक करें। दो अन्य बटनों के दाईं ओर स्थित "टिप्पणियाँ" टेक्स्ट फ़ील्ड के नीचे स्थित "शॉर्टकट" टैब के नीचे क्रमशः "उन्नत" बटन पर क्लिक करें, "फ़ाइल खोलें स्थान" और "बदलें आइकन" क्रमशः।

"प्रशासक के रूप में चलाएं" पढ़ने वाले चेकबॉक्स को चेक करें। ठीक क्लिक करें, फिर लागू करें और ठीक है । एक बार फिर से C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell में स्थित 'Windows PowerShell' लेबल वाले आइकन पर राइट क्लिक करें और "मेनू / टास्कबार प्रारंभ करने के लिए पिन करें" का चयन करें।

अब जब भी आप उस आइकन पर क्लिक करेंगे, तो यह बढ़ने के लिए UAC आह्वान करेगा। 'हां' चुनने के बाद, आप पावरशेल कंसोल खोलेंगे और इसे स्क्रीन के शीर्ष पर "व्यवस्थापक" लेबल किया जाएगा।

एक कदम आगे जाने के लिए ... आप Windows PowerShell के अपने प्रोफ़ाइल स्थान पर उसी आइकन शॉर्टकट पर राइट क्लिक कर सकते हैं और एक कीबोर्ड शॉर्टकट असाइन कर सकते हैं जो सटीक वही काम करेगा जैसे आपने हाल ही में जोड़े गए आइकन पर क्लिक किया था। तो जहां यह कहता है कि "शॉर्टकट कुंजी" कुंजीपटल कुंजी / बटन संयोजन में डाल दिया गया है जैसे: Ctrl + Alt + P P (PowerShell के लिए)लागू करें और ठीक क्लिक करें

अब आपको बस इतना करना है कि आपके द्वारा असाइन किए गए बटन संयोजन को दबाएं और आप यूएसी को बुलाएंगे, और 'YES' चुनने के बाद आपको एक पावरशेल कंसोल दिखाई देगा और टाइटल बार पर प्रदर्शित "व्यवस्थापक" दिखाई देगा।




कमांड के आउटपुट को टेक्स्ट फ़ाइल नाम में जोड़ने के लिए जिसमें वर्तमान दिनांक शामिल है, आप ऐसा कुछ कर सकते हैं:

$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 }



.ps1 फ़ाइलों के लिए "व्यवस्थापक के रूप में चलाएं" संदर्भ मेनू प्राप्त करने के लिए आप आसानी से कुछ रजिस्ट्री प्रविष्टियां जोड़ सकते हैं:

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"'

(@Shay से एक सरल लिपि में अपडेट किया गया)

मूल रूप से HKCR:\Microsoft.PowershellScript.1\Shell\runas\command का उपयोग करके स्क्रिप्ट को आमंत्रित करने के लिए डिफ़ॉल्ट मान सेट करता है।




Related