visual studio 2012 multiple -commands in command line arguments - visual-studio-2012

In visual studio 2012 it is possible on the debug-> start options to specify command line arguments. I am working on a powershell cmdlet so I'd like to be able to parse multiple commands into powershell. My arguments looks like this
-noexit -command add-pssnapin Registerv2.0 -command New-Token -command www.google.com
the problem is it is treating -command as 1 long string i.e -command "add-pssnapin Registerv2.0 -command New-Token -command www.google.com" rather then 3 seperae commands. Does anyone know how to change this:
edit
the results I am looking for is when I run the project
power shell opens
my snapin is registered
Call the cmdlet new-token
enter in the cmdlet parameters

If you first want add-pssnapin Registerv2.0 and then New-Token to be called, you should chain them in one command, like so:
-command "add-pssnapin Registerv2.0; New-Token"
If New-Token expects a parameter, you should pass it on the command line directly, instead of trying to simulate user input.
For example, New-Item would expect a list of paths and a type as input, both can also be supplied on the command line as parameters. Like so:
New-Item foo -type directory
So, how you would pass the value www.google.com to New-Token depends on the name of the parameter. But could look like:
-command "add-pssnapin Registerv2.0; New-Token -tokenName www.google.com"

Related

Cannot convert string to boolean - ansible to powershell on linux

I read this whole thread about how to pass boolean values to a parameter to powershell on Linux. Nothing worked for me.
My code in Ansible is as follows:
- name: Install PowerCLI
shell: pwsh -Command "Set-PowerCLIConfiguration -Scope AllUsers -ParticipateInCEIP:$False -Confirm:$False -InvalidCertificateAction Ignore"
I've used many variants, such as -ParticipateInCEIP:False, or -ParticipateInCEIP False, or -ParticipateInCEIP $false, but I get always the same error, that it expects boolean, but I sent string.
I am running this Ansible task against a Linux machine with Powershell installed.
Any tips on how to make it work?
Best,
Francis
When you shell: pwsh -Command "something -switch:$powershellVariable", with double quotes, $powershellVariable will be evaluated by the Linux shell before passing it to PowerShell.
Unless you have an actual $powershellVariable defined in your shell, it will be passed to PowerShell as something -switch:
Try rewriting with single quotes:
shell: pwsh -Command 'Set-PowerCLIConfiguration -Scope AllUsers -ParticipateInCEIP:$False -Confirm:$False -InvalidCertificateAction Ignore'

azure VM extension Powershell Custom script

I want to pass the variables inside my terraform script when I call the PowerShell script inside "azurerm_virtual_machine_extension". i don't know how to pass arguments to my powershell script. I have used the following code.
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -file ${var.main_hybridscriptname} -AAResourceGroupName ${var.aobclResourceGroup} -OMSResourceGroupName ${var.aobclResourceGroup} -SubscriptionID ${var.azure_subscription_id} -AutomationAccountName ${module.automationAccount.AutomationName} -HybridGroupName ${var.hybridgroupname} -WorkspaceName ${azurerm_log_analytics_workspace.aobclloganalyticsworkspace.name} -appidSPN ${var.SPN_APP_ID} -SPNpswd ${var.SPN_PSWD} -tenantID ${var.azure_tenant_id}"
error in script execution when i use a script of test without argument, it worksstrong text

executing the powershell commands using python

import os
os.system("powershell.exe [Get-ItemProperty
HKLM:\\Software\\Wow6432Node\\Microsoft\\\Windows\\CurrentVersion\\Uninstall\\*| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize > D:\\application whitelisting\\InstalledProgramsPS.txt ]")
this is my code. I want to display the list of software installed in the system.
but i am getting error like
Select-Object is not recognized as an external or internal command.
when i execute the same command using powershell, it is working fine.
can anyone please help?
thanks in advance.
The reason is that Powershell's command parameter is not properly constructed. os.system() call will star a CMD session, and Select-Object is not recognized as an external or internal command is an error message from CMD.
Let's see what CMD does. First it will run Powershell and pass some arguments. Note the triple backslash, which is an error by itself and needs to be fixed.
powershell.exe [Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\\Windows\\CurrentVersion\\Uninstall\\*
| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
Now, the first thing is that Powershell is invoked and (wrongly) paramerized Get-ItemProperty is passed. Because the pipe char | is used in CMD as well, it is interpreted as a command for CMD. Thus CMD tries to pipe the first command's output to Select-Object, but there isn't such a command in CMD. Thus the error.
To fix the issue, use -command "<commands>" to pass commands to Powershell. The double quotes " are used to create a single string that CMD passes to Powershell as an argument.
powershell.exe -command "Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table -AutoSize > D:\\application whitelisting\\InstalledProgramsPS.txt"

PowerShell Start-Process loses precision on number passed as a string to a function

I have some code that edits the registry, so it needs to run as admin. To do this, I start up a new PowerShell process from my running PowerShell script, and pass in part of the registry key path, which happens to be a version number, e.g. "12.0". The function in the new PowerShell process receives the string as "12" though, not "12.0", and so I'm getting errors that it can't find the registry key.
I've created a little sample powershell script that reproduces the problem. Here's the snippet:
$ScriptBlock = {
function Test([string]$VisualStudioVersion)
{
$VisualStudioVersion # This always displays 12, instead of 12.0
$Host.UI.RawUI.ReadKey()
}
}
# Run the script block's function.
Start-Process -FilePath PowerShell -ArgumentList "-Command & {$ScriptBlock Test(""12.0"")}"
Here I've hardcoded "12.0", but in practice I want to pass in a variable.
Any ideas on what I'm doing wrong? Thanks in advance.
Ok, after some experimenting the following seems to work correctly:
Start-Process -FilePath PowerShell -ArgumentList "-Command & {$ScriptBlock Test('12.0')}"
and it even works when using a variable:
$version = "12.0"
Start-Process -FilePath PowerShell -ArgumentList "-Command & {$ScriptBlock Test('$version')}"
I'm still not sure why using double quotes causes it to lose the precision and single quotes keeps it, but at least I solved my problem.
Update
So it turns out I'm a dummy and the problem was that I was using C# syntax of Test(""$version"") to call the function, instead of the proper PowerShell syntax Test ""version"". With this change it now works as expected.

How do you call msdeploy from powershell when the parameters have spaces?

I'm running into a problem with spaces in my parameters that I try to send into msdeploy from a powershell script.
There are a number of other related articles but none of them solve the problem.
Problems Using Power Shell And MSDeploy.
Similar SO issue that doesn't work: How to run exe in powershell with parameters with spaces and quotes
PowerShell BUG: Executing commands which require quotes and variables is practically impossible
Another SO issue that doesn't work:Passing parameters in PowerShell 2.0
The simplest example that succeeds and then fails when I make it more complicated is just dumping the default web site.
$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
&$msdeploy -verb:dump -source:appHostConfig=`'default web site`' -verbose
==SUCCESS
This one?
$sitename="default web site"
&$msdeploy -verb:dump -source:appHostConfig=$sitename -verbose
==FAIL with the following error
msdeploy.exe : Error: Unrecognized argument '"-source:"appHostConfig=default'. All arguments must begin with "-".
At C:\xxx\test.ps1:122 char:6
+ &
+ CategoryInfo : NotSpecified: (Error: Unrecogn...begin with "-".:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Error count: 1.
The following variations have also failed
#FAIL
$sitename=`'default web site`'
$sitename=`'"default web site"`'
$sitename="`'default web site`'"
$sitename="default web site"
$sitename="'default web site'"
&$msdeploy -verb:dump "-source:appHostConfig=$sitename" -verbose
&$msdeploy -verb:dump -source:appHostConfig="$sitename" -verbose
&$msdeploy -verb:dump -source:appHostConfig='$sitename' -verbose
&$msdeploy -verb:dump -source:appHostConfig=`'$sitename`' -verbose
&$msdeploy -verb:dump -source:appHostConfig=`"$sitename`" -verbose
I'm at a loss. Everyone I work with is at a loss. Seriously this sucks. I loved Powershell. I loved msdeploy. I can't say that I love putting them together. It looks like it may have been easier to focus on the API instead of the cli.
EDIT:
The parameters in the string array suggested by Emperor XLII works well. An alternative solution is presented in the following article: The trials and tribulations of using MSDeploy with PowerShell
function PushToTarget([string]$server, [string]$remotePath, [string]$localPath) {
cmd.exe /C $("msdeploy.exe -verb:sync -source:contentPath=`"{0}`" -dest:computerName=`"{1}`",contentPath=`"{2}`" -whatif" -f $localPath, $server, $remotePath )
}
Using the technique from Keith's answer to How to run exe in powershell with parameters with spaces and quotes question you linked to, running echoargs -verb:dump -source:appHostConfig=$sitename -verbose gave me this output:
Arg 0 is <-verb:dump>
Arg 1 is <-source:appHostConfig=default>
Arg 2 is <web>
Arg 3 is <site>
Arg 4 is <-verbose>
This would explain the invalid argument of appHostConfig=default that msdeploy was seeing.
Running echoargs -verb:dump "-source:appHostConfig=$sitename" -verbose, with $sitename = "default web site", appears to result in the desired arguments:
Arg 0 is <-verb:dump>
Arg 1 is <-source:appHostConfig=default web site>
Arg 2 is <-verbose>
Though from your list, it appears that this did not work for you.
Another method you might try is building up the list of arguments in an array, which powershell can automatically escape. For example, this gives the same output as above:
[string[]]$msdeployArgs = #(
"-verb:dump",
"-source:appHostConfig=$sitename",
"-verbose"
)
echoargs $msdeployArgs
Just adding another way in case it is helpful to anyone:
Invoke-Expression "& '[path to msdeploy]\msdeploy.exe' --% -verb:sync -source:contentPath=`'$source`' -dest:contentPath=`'$dest`'"
"--%" is new to powershell 3. From here: "You simply add a the --% sequence (two dashes and a percent sign) anywhere in the command line and PowerShell will not try to parse the remainder of that line."
Found a working solution and easy fix.
Reference: http://answered.site/all-arguments-must-begin-with--at-cwindowsdtldownloadswebserviceswebservicesidservicepublishedwebsitesidservicedeploymentidservicewsdeployps123/4231580/
$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe"
$msdeployArgs = #(
"-verb:sync",
"-source:iisApp='Default Web Site/HelloWorld'",
"-verbose",
"-dest:archiveDir='c:\temp1'"
)
Start-Process $msdeploy -NoNewWindow -ArgumentList $msdeployArgs
We had faced the similar kind of issue. Our fix was like below,
$path = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";
$verb = "-verb:sync";
$src = "-source:contentPath=[ESC][ESC][ESC]"c:\aa aa[ESC][ESC][ESC]";
$dest = "-dest:contentPath=[ESC][ESC][ESC]"c:\aa[ESC][ESC][ESC]";
Invoke-Expression "&'$path' $verb $src $dest";
where, ESC - is escape sequence/character
I tried every technique under the sun, and this is the only one that worked for me (using PowerShell 2).
cmd.exe /C $("msdeploy.exe -verb:sync -source:package=`"{0}`" -dest:auto,IncludeAcls=`"False`" -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:`"{1}`"" -f $mypackagepath, $myparamfilepath )
Here is another approach derived from the input below.
$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";
$command = "-verb:sync";
$sourcePath = "C:\aa aa\";
$source = $("-source:contentPath=`"{0}`"" -f $sourcePath);
$destPath = "C:\aa"
$destination = $("-dest:contentPath=`"{0}`" -f $destPath);
$msdeploycommand = $("`"{0}`" {1} {2} {3} -verbose" -f $msdeploy, $command, $source, $destination);
cmd.exe /C "`"$msdeploycommand`"";
This caters for the MSDeploy.exe being in its default installation folder which contains spaces. Hence the wrapping with the escape character (`).
I've used some ideas from answers above and came up with the following simpler function to do the thing.
Note that it is important to give the full path to MSDeploy as when running under the build agent it sometimes doesnt recognise the PATH to msdeploy.
function Deploy([string]$server, [string]$remotePath, [string]$localPath) {
$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";
cmd.exe /C $("`"{3}`" -verb:sync -source:contentPath=`"{0}`" -dest:computerName=`"{1}`",contentPath=`"{2}`" " -f $localPath, $server, $remotePath , $msdeploy )
}
Usage
Deploy $hostName $remotePath $source
All of the above did not work for me, this is the solution that worked:
# get msdeploy exe
$MSDeploy = ${env:ProgramFiles}, ${env:ProgramFiles(x86)} |
ForEach-Object {Get-ChildItem -Path $_ -Filter 'MSDeploy.exe' -Recurse} |
Sort-Object -Property #{Expression={[version]$_.VersionInfo.FileVersion}} -Descending |
Select-Object -First 1 -ExpandProperty FullName
#build deploy command
$deplyCmd = """""$MSDeploy"" -verb:sync -dest:iisApp=""Default Web Site"" -enableRule:DoNotDeleteRule -source:iisApp=""$ExtraWebFilesFolder"""
#execute
&cmd /c $deplyCmd
This problem has certainly been around for a long time and I spent some time battling it recently. The result has been successful for me so I'll post it here in hopes that it can help others who find this question in the future.
The first problem to resolve is getting rid of the spaces in the msdeploy path. There are two approaches here. One is persistent and requires you to have server access, the other is temporary in the context of your PowerShell script. Either will work but I'd prefer the first if it's an option for you.
For the first approach, create a junction point. Example script:
new-item -Path "c:\MS-WebDeploy" -ItemType Junction -Value "c:/Program Files (x86)/iis/microsoft web deploy v3"
For the second approach, create a PSDrive (w in this example)
New-PSDrive -Name "w" -PSProvider FileSystem -Root "C:/Program Files (x86)/iis/microsoft web deploy v3"
I'm using three PowerShell variables below. For example purposes, pretend that all three have spaces.
$ParamFilePath = "c:\deployment files\parameters.xml"
$PackageName = "c:\deployment files\My Website.zip"
$WebAppPath = "Default Web Site"
First, create an array and build up your arguments as needed.
#nothing needs to be done with these arguments so we'll start with them
[string[]]$arguments = #("-verb:sync", "-dest:auto", "-disableLink:AppPoolExtension", "-disableLink:ContentExtension", "-disableLink:CertificateExtension", "-allowUntrusted")
#double up on the quotes for these paths after the colon
$arguments += "-setParamFile:""$ParamFilePath"""
$arguments += "-source:package=""$PackageName"""
#must not have spaces with the commma, use single quotes on the name and value here
$arguments += "-setParam:name='IIS Web Application Name',value='$WebAppPath'"
#add your own logic for optional arguments
$arguments += "-EnableRule:EncryptWebConfig"
Now build the msdeploy command and put the PowerShell escape sequence to prevent PowerShell from "helping" later. Use the path you created with the junction or the PSDrive
$command = "w:\msdeploy.exe" + " --% " + $arguments -join " "
Finally, execute that command as a script block.
$sb = $ExecutionContext.InvokeCommand.NewScriptBlock($command)
& $sb
I've wrapped this and a bit more code into a script which is called like this.
.\Run-WebDeploy -WebAppPath "Default Web Site" -PackageName "c:\deployment files\My Website.zip" -ParamFilePath "c:\deployment files\parameters.xml" -EncryptWebConfig
In general, you can help yourself a lot by getting rid of the spaces in your paths/names. Sometimes, that can't be done and this should get you through.

Resources