كيفية تشغيل ملف EXE في PowerShell مع المعلمات مع مسافات وعلامات الاقتباس




parameters quotes (9)

استطعت الحصول على أمر مشابه يعمل باستخدام النهج التالي:

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql

لأمرك (ليس أنه يساعد الكثير الآن) ، ستبدو الأمور كما يلي:

msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

النقاط الرئيسية هي:

  • استخدم علامات الاقتباس حول الوسيطة المصدر ، وقم بإزالة علامات الاقتباس المضمنة حول سلسلة الاتصال
  • استخدم أسماء المفاتيح البديلة في إنشاء سلسلة اتصال SQL التي لا تحتوي على مسافات فيها. على سبيل المثال ، استخدم "UID" بدلاً من "User Id" ، "Server" بدلاً من "Data Source" ، "Trusted_Connection" بدلاً من "Integrated Security" ، وهكذا. لم أتمكن من الحصول عليه إلا بعد إزالة جميع المسافات من سلسلة الاتصال.

لم أحاول إضافة جزء "computername" في نهاية سطر الأوامر ، ولكن نأمل أن تساعد هذه المعلومات الآخرين في قراءة هذا الآن الاقتراب من النتيجة المرجوة.

كيف تقوم بتشغيل الأمر التالي في PowerShell؟

C: \ Program Files \ IIS \ Microsoft Web Deploy \ msdeploy.exe -verb: sync -source: dbfullsql = "مصدر البيانات = mysource ؛ الأمان المتكامل = false ؛ معرف المستخدم = sa ؛ Pwd = sapass! ؛ Database = mydb؛" -dest: dbfullsql = "مصدر البيانات =. \ mydestsource ؛ الأمان المتكامل = false ؛ معرف المستخدم = sa ؛ Pwd = sapass! ؛ Database = mydb؛" ، computername = 10.10.10.10 ، username = administrator ، password = adminpass "


الإجابة البديلة هي استخدام مفتاح أمر ترميز Base64 :

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="

عند فك ترميزه ، سترى أنه مقتطف OP الأصلي مع جميع الحجج والعلامات المزدوجة المحفوظة.

powershell.exe -EncodedCommand

Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

الأمر الأصلي:

 C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

يتحول إلى هذا عند ترميزه ك Base64:

QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==

وهنا كيفية تكرار في المنزل:

$command = 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand

#  The clip below copies the base64 string to your clipboard for right click and paste.
$encodedCommand | Clip

حاولت جميع الاقتراحات ولكن كان لا يزال غير قادر على تشغيل msiexec.exe مع المعلمات التي تحتوي على مسافات. لذلك انتهى الحل بلدي باستخدام System.Diagnostics.ProcessStartInfo :

# can have spaces here, no problems
$settings = @{
  CONNECTION_STRING = "... ..."
  ENTITY_CONTEXT = "... ..."
  URL = "..."
}

$settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " "
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.WorkingDirectory = $ScriptDirectory
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()

سلسلة هروب جديدة في PowerShell V3 ، مقتبسة من ميزات لغة V3 الجديدة :

أسهل إعادة استخدام خطوط الأوامر من Cmd.exe

شبكة الإنترنت مليئة بخطوط الأوامر المكتوبة لـ Cmd.exe. تعمل سطور الأوامر هذه بشكلٍ كافٍ في PowerShell ، ولكن عندما تتضمن أحرفًا معينة ، على سبيل المثال ، فاصلة منقوطة (؛) أو علامة الدولار ($) أو أقواس معقوفة ، عليك إجراء بعض التغييرات ، وربما إضافة بعض الأسعار. هذا يبدو أن مصدر العديد من الصداع الطفيف.

للمساعدة في معالجة هذا السيناريو ، أضفنا طريقة جديدة "للهروب" من تحليل خطوط الأوامر. إذا كنت تستخدم معلمة سحرية -٪ ، فسنوقف التحليل العادي لخط الأوامر الخاص بك والتبديل إلى شيء أكثر بساطة. نحن لا نطابق الأسعار. نحن لا نتوقف عند الفاصلة المنقوطة. نحن لا نقوم بتوسيع متغيرات PowerShell. نقوم بتوسيع متغيرات البيئة إذا كنت تستخدم بناء الجملة Cmd.exe (على سبيل المثال٪ TEMP٪). بخلاف ذلك ، يتم تمرير الحجج حتى نهاية السطر (أو الأنبوب ، إذا كنت piping) كما هو. هنا مثال:

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>

في حال تساءل شخص ما عن كيفية تشغيل ملف قابل للتنفيذ:

.....>. \ file.exe

أو

......> full \ path \ to \ file.exe


كان لدي مساحات في كلٍ من الأوامر والمعلمات ، وهذا هو ما نجحت في تحقيقه:

$Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe"
$Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL"

$Prms = $Parms.Split(" ")
& "$Command" $Prms

إنه في الأساس نفس إجابة Akira ، ولكن هذا يعمل إذا قمت بإنشاء معلمات الأوامر الخاصة بك بشكل ديناميكي ووضعها في متغير.


ما عليك سوى إضافة عامل التشغيل & قبل اسم .exe. فيما يلي أمر لتثبيت SQL Server Express في وضع السكون:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe"
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini"

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

هذا العمل بالنسبة لي:

& 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar')

فقط ضع مسارات أو سلاسل اتصال في عنصر صفيف واحد وقم بتقسيم الأشياء الأخرى في عنصر صفيف واحد لكل منها.

هناك الكثير من الخيارات الأخرى هنا: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

يجب أن تجعل Microsoft هذه الطريقة أبسط ومتوافقة مع بناء جملة أوامر الأوامر.


هناك عدد غير قليل من الطرق التي يمكنك استخدامها للقيام بذلك.

هناك طرق أخرى مثل استخدام Call Operator ( & ) ، Invoke-Expression cmdlet إلخ. ولكنها تعتبر غير آمنة. توصي Microsoft باستخدام Start-Process .

طريقة 1

مثال بسيط

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"

في حالتك

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass"

في هذه الطريقة تقوم بفصل كل معلمة في ArgumentList باستخدام الفواصل.

الطريقة الثانية

مثال بسيط

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"

في حالتك

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass"

هذه الطريقة أسهل لأنها تسمح لك بكتابة المعلمات دفعة واحدة.

لاحظ أنه في powerhell لتمثيل علامة الاقتباس (") في سلسلة يجب عليك إدراج اللكنة القبر (`) (هذا هو المفتاح فوق مفتاح Tab في لوحة المفاتيح الأمريكية).

-المعلمة -NoNewWindow تُستخدم لعرض العملية الجديدة في إطار وحدة التحكم الحالية. افتراضيًا ، يقوم Windows PowerShell بفتح نافذة جديدة.

المراجع: Powershell/Scripting/Start-Process





spaces