Deploying SharePoint 2010 Solution Package Using PowerShell (Revisited)
If you were at my PowerShell for developers talk at the European SharePoint Best Practices Conference last week then you’ll know that I’ve never been all that happy with how I was approaching Farm Solution deployment, as detailed in an earlier post from sometime last year (Deploying SharePoint 2010 Solution Packages Using PowerShell). So what are some of the issues I have with what I created? Here’s a quick list:
- There are two functions – I really just want one function to call and let the function figure out what to do based on the parameters provided.
- I want to be able to provide a directory containing WSP files to deploy (sure, I could use Get-ChildItem to grab all my files, iterate through them, and then call the function, but that means I have to type more each time I want to execute and I’m way too lazy for that).
- There’s no consideration for simply updating Solution Packages rather than retracting and redeploying.
- I was using the Start-SPAdminJob cmdlet and stopping and starting the admin service – something that we shouldn’t be doing and is really just an old throwback to 2007. It’s just a bad idea – don’t do it.
- I was forcing information such as GAC and CAS settings in the XML when I could easily get the information via the SPSolution object once added.
- And finally, there was no real help available so you had to really know what was going on to understand how to construct the XML file and to then call the file.
For all these reasons I’ve decided to completely rewrite the script. As a result it’s a bit more complicated at first blush but that’s mainly due to some additional error handling, progress reporting, and blocking code that I’ve added; as well as the additional parameter related code and associated help. I’ve essentially followed the pattern that I described with my earlier post on Feature activation and have made the function work more like a cmdlet (with full help, parameter sets, and use of PipeBind objects). Before I share the code, I’d like to show the complete help that is available for the function:
NAME
Deploy-SPSolutions
SYNOPSIS
Deploys one or more Farm Solution Packages to the Farm.
SYNTAX
Deploy-SPSolutions [-Identity] <String> [[-UpgradeExisting]] [[-AllWebApplications]] [[-WebApplication] <SPWebApplicationPipeBind[]>] [<CommonParameters>]
Deploy-SPSolutions [-Config] <XmlDocument> [<CommonParameters>]
DESCRIPTION
Specify either a directory containing WSP files, a single WSP file, or an XML configuration file containing the WSP files to deploy.
If using an XML configuration file, the format of the file must match the following:
<Solutions>
<Solution Path="<full path and filename to WSP>" UpgradeExisting="false">
<WebApplications>
<WebApplication>http://example.com/</WebApplication>
</WebApplications>
</Solution>
</Solutions>
Multiple <Solution> and <WebApplication> nodes can be added. The UpgradeExisting attribute is optional and should be specified if the WSP should be udpated and not retracted and redeployed.
PARAMETERS
-Config <XmlDocument>
The XML configuration file containing the WSP files to deploy.
Required? true
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters?
-Identity <String>
The directory, WSP file, or XML configuration file containing the WSP files to deploy.
Required? true
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters?
-UpgradeExisting [<SwitchParameter>]
If specified, the WSP file(s) will be updated and not retracted and redeployed (if the WSP does not exist in the Farm then this parameter has no effect).
Required? false
Position? 2
Default value
Accept pipeline input? false
Accept wildcard characters?
-AllWebApplications [<SwitchParameter>]
If specified, the WSP file(s) will be deployed to all Web Applications in the Farm (if applicable).
Required? false
Position? 3
Default value
Accept pipeline input? false
Accept wildcard characters?
-WebApplication <SPWebApplicationPipeBind[]>
Specifies the Web Application(s) to deploy the WSP file to.
Required? false
Position? 4
Default value
Accept pipeline input? false
Accept wildcard characters?
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer and OutVariable. For more information, type,
"get-help about_commonparameters".
INPUTS
OUTPUTS
-------------------------- EXAMPLE 1 --------------------------
PS C:\>. .\Deploy-SPSolutions.ps1
PS C:\> Deploy-SPSolutions -Identity C:\WSPs -WebApplication http://demo
This example loads the function into memory and then deploys all the WSP files in the specified directory to the http://demo Web Application (if applicable).
-------------------------- EXAMPLE 2 --------------------------
PS C:\>. .\Deploy-SPSolutions.ps1
PS C:\> Deploy-SPSolutions -Identity C:\WSPs -WebApplication http://demo,http://mysites
This example loads the function into memory and then deploys all the WSP files in the specified directory to the http://demo and http://mysites Web Applications (if applicable).
-------------------------- EXAMPLE 3 --------------------------
PS C:\>. .\Deploy-SPSolutions.ps1
PS C:\> Deploy-SPSolutions -Identity C:\WSPs -AllWebApplications
This example loads the function into memory and then deploys all the WSP files in the specified directory to all Web Applications (if applicable).
-------------------------- EXAMPLE 4 --------------------------
PS C:\>. .\Deploy-SPSolutions.ps1
PS C:\> Deploy-SPSolutions -Identity C:\WSPs\MyCustomSolution.wsp -AllWebApplications
This example loads the function into memory and then deploys the specified WSP to all Web Applications (if applicable).
-------------------------- EXAMPLE 5 --------------------------
PS C:\>. .\Deploy-SPSolutions.ps1
PS C:\> Deploy-SPSolutions -Identity C:\WSPs\MyCustomSolution.wsp -AllWebApplications -UpgradeExisting
This example loads the function into memory and then deploys the specified WSP to all Web Applications (if applicable); existing deployments will be upgraded and not retracted and redeployed.
-------------------------- EXAMPLE 6 --------------------------
PS C:\>. .\Deploy-SPSolutions.ps1
PS C:\> Deploy-SPSolutions C:\Solutions.xml
This example loads the function into memory and then deploys all the WSP files specified by the Solutions.xml configuration file.
RELATED LINKS
Get-Content
Get-SPSolution
Add-SPSolution
Install-SPSolution
Update-SPSolution
Uninstall-SPSolution
Remove-SPSolution
As you can see, this is a lot more useful for someone wishing to execute this script as not only does it provide information about the XML structure but it also provides several usage examples.
So, without further delay, here’s the new version of the deployment script (note that I changed the function name to Deploy-SPSolutions so it won’t impact environments that depend on the old function):
function global:Deploy-SPSolutions() { <# .Synopsis Deploys one or more Farm Solution Packages to the Farm. .Description Specify either a directory containing WSP files, a single WSP file, or an XML configuration file containing the WSP files to deploy. If using an XML configuration file, the format of the file must match the following: <Solutions> <Solution Path="<full path and filename to WSP>" UpgradeExisting="false"> <WebApplications> <WebApplication>http://example.com/</WebApplication> </WebApplications> </Solution> </Solutions> Multiple <Solution> and <WebApplication> nodes can be added. The UpgradeExisting attribute is optional and should be specified if the WSP should be udpated and not retracted and redeployed. .Example PS C:\> . .\Deploy-SPSolutions.ps1 PS C:\> Deploy-SPSolutions -Identity C:\WSPs -WebApplication http://demo This example loads the function into memory and then deploys all the WSP files in the specified directory to the http://demo Web Application (if applicable). .Example PS C:\> . .\Deploy-SPSolutions.ps1 PS C:\> Deploy-SPSolutions -Identity C:\WSPs -WebApplication http://demo,http://mysites This example loads the function into memory and then deploys all the WSP files in the specified directory to the http://demo and http://mysites Web Applications (if applicable). .Example PS C:\> . .\Deploy-SPSolutions.ps1 PS C:\> Deploy-SPSolutions -Identity C:\WSPs -AllWebApplications This example loads the function into memory and then deploys all the WSP files in the specified directory to all Web Applications (if applicable). .Example PS C:\> . .\Deploy-SPSolutions.ps1 PS C:\> Deploy-SPSolutions -Identity C:\WSPs\MyCustomSolution.wsp -AllWebApplications This example loads the function into memory and then deploys the specified WSP to all Web Applications (if applicable). .Example PS C:\> . .\Deploy-SPSolutions.ps1 PS C:\> Deploy-SPSolutions -Identity C:\WSPs\MyCustomSolution.wsp -AllWebApplications -UpgradeExisting This example loads the function into memory and then deploys the specified WSP to all Web Applications (if applicable); existing deployments will be upgraded and not retracted and redeployed. .Example PS C:\> . .\Deploy-SPSolutions.ps1 PS C:\> Deploy-SPSolutions C:\Solutions.xml This example loads the function into memory and then deploys all the WSP files specified by the Solutions.xml configuration file. .Parameter Config The XML configuration file containing the WSP files to deploy. .Parameter Identity The directory, WSP file, or XML configuration file containing the WSP files to deploy. .Parameter UpgradeExisting If specified, the WSP file(s) will be updated and not retracted and redeployed (if the WSP does not exist in the Farm then this parameter has no effect). .Parameter AllWebApplications If specified, the WSP file(s) will be deployed to all Web Applications in the Farm (if applicable). .Parameter WebApplication Specifies the Web Application(s) to deploy the WSP file to. .Link Get-Content Get-SPSolution Add-SPSolution Install-SPSolution Update-SPSolution Uninstall-SPSolution Remove-SPSolution #> [CmdletBinding(DefaultParameterSetName="FileOrDirectory")] param ( [Parameter(Mandatory=$true, Position=0, ParameterSetName="Xml")] [ValidateNotNullOrEmpty()] [xml]$Config, [Parameter(Mandatory=$true, Position=0, ParameterSetName="FileOrDirectory")] [ValidateNotNullOrEmpty()] [string]$Identity, [Parameter(Mandatory=$false, Position=1, ParameterSetName="FileOrDirectory")] [switch]$UpgradeExisting, [Parameter(Mandatory=$false, Position=2, ParameterSetName="FileOrDirectory")] [switch]$AllWebApplications, [Parameter(Mandatory=$false, Position=3, ParameterSetName="FileOrDirectory")] [Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind[]]$WebApplication ) function Block-SPDeployment($solution, [bool]$deploying, [string]$status, [int]$percentComplete) { do { Start-Sleep 2 Write-Progress -Activity "Deploying solution $($solution.Name)" -Status $status -PercentComplete $percentComplete $solution = Get-SPSolution $solution if ($solution.LastOperationResult -like "*Failed*") { throw "An error occurred during the solution retraction, deployment, or update." } if (!$solution.JobExists -and (($deploying -and $solution.Deployed) -or (!$deploying -and !$solution.Deployed))) { break } } while ($true) sleep 5 } switch ($PsCmdlet.ParameterSetName) { "Xml" { # An XML document was provided so iterate through all the defined solutions and call the other parameter set version of the function $Config.Solutions.Solution | ForEach-Object { [string]$path = $_.Path [bool]$upgrade = $false if (![string]::IsNullOrEmpty($_.UpgradeExisting)) { $upgrade = [bool]::Parse($_.UpgradeExisting) } $webApps = $_.WebApplications.WebApplication Deploy-SPSolutions -Identity $path -UpgradeExisting:$upgrade -WebApplication $webApps -AllWebApplications:$(($webApps -eq $null) -or ($webApps.Length -eq 0)) } break } "FileOrDirectory" { $item = Get-Item (Resolve-Path $Identity) if ($item -is [System.IO.DirectoryInfo]) { # A directory was provided so iterate through all files in the directory and deploy if the file is a WSP (based on the extension) Get-ChildItem $item | ForEach-Object { if ($_.Name.ToLower().EndsWith(".wsp")) { Deploy-SPSolutions -Identity $_.FullName -UpgradeExisting:$UpgradeExisting -WebApplication $WebApplication } } } elseif ($item -is [System.IO.FileInfo]) { # A specific file was provided so assume that the file is a WSP if it does not have an XML extension. [string]$name = $item.Name if ($name.ToLower().EndsWith(".xml")) { Deploy-SPSolutions -Config ([xml](Get-Content $item.FullName)) return } $solution = Get-SPSolution $name -ErrorAction SilentlyContinue if ($solution -ne $null -and $UpgradeExisting) { # Just update the solution, don't retract and redeploy. Write-Progress -Activity "Deploying solution $name" -Status "Updating $name" -PercentComplete -1 $solution | Update-SPSolution -CASPolicies:$($solution.ContainsCasPolicy) ` -GACDeployment:$($solution.ContainsGlobalAssembly) ` -LiteralPath $item.FullName Block-SPDeployment $solution $true "Updating $name" -1 Write-Progress -Activity "Deploying solution $name" -Status "Updated" -Completed return } if ($solution -ne $null) { #Retract the solution if ($solution.Deployed) { Write-Progress -Activity "Deploying solution $name" -Status "Retracting $name" -PercentComplete 0 if ($solution.ContainsWebApplicationResource) { $solution | Uninstall-SPSolution -AllWebApplications -Confirm:$false } else { $solution | Uninstall-SPSolution -Confirm:$false } #Block until we're sure the solution is no longer deployed. Block-SPDeployment $solution $false "Retracting $name" 12 Write-Progress -Activity "Deploying solution $name" -Status "Solution retracted" -PercentComplete 25 } #Delete the solution Write-Progress -Activity "Deploying solution $name" -Status "Removing $name" -PercentComplete 30 Get-SPSolution $name | Remove-SPSolution -Confirm:$false Write-Progress -Activity "Deploying solution $name" -Status "Solution removed" -PercentComplete 50 } #Add the solution Write-Progress -Activity "Deploying solution $name" -Status "Adding $name" -PercentComplete 50 $solution = Add-SPSolution $item.FullName Write-Progress -Activity "Deploying solution $name" -Status "Solution added" -PercentComplete 75 #Deploy the solution if (!$solution.ContainsWebApplicationResource) { Write-Progress -Activity "Deploying solution $name" -Status "Installing $name" -PercentComplete 75 $solution | Install-SPSolution -GACDeployment:$($solution.ContainsGlobalAssembly) -CASPolicies:$($solution.ContainsCasPolicy) -Confirm:$false Block-SPDeployment $solution $true "Installing $name" 85 } else { if ($WebApplication -eq $null -or $WebApplication.Length -eq 0) { Write-Progress -Activity "Deploying solution $name" -Status "Installing $name to all Web Applications" -PercentComplete 75 $solution | Install-SPSolution -GACDeployment:$($solution.ContainsGlobalAssembly) -CASPolicies:$($solution.ContainsCasPolicy) -AllWebApplications -Confirm:$false Block-SPDeployment $solution $true "Installing $name to all Web Applications" 85 } else { $WebApplication | ForEach-Object { $webApp = $_.Read() Write-Progress -Activity "Deploying solution $name" -Status "Installing $name to $($webApp.Url)" -PercentComplete 75 $solution | Install-SPSolution -GACDeployment:$gac -CASPolicies:$cas -WebApplication $webApp -Confirm:$false Block-SPDeployment $solution $true "Installing $name to $($webApp.Url)" 85 } } } Write-Progress -Activity "Deploying solution $name" -Status "Deployed" -Completed } break } } }
When it comes to using the function I believe the help documentation speaks for itself so I won’t reiterate it here.
As always, I’m open to suggestions as to how to improve this function so please leave a comment if you find something wrong or have a suggestion for making it better.
-Gary
April 19th, 2011 - 04:24
Hi Gary,
I followed your session at the BPCUK but…
When i’m running the above code like:
. .\Deploy.ps1
Deploy-SPSolution -Config .\Solutions.xml
I receive an error like “Data at the root is invalid”.
Any idea’s?
Kind regards,
April 19th, 2011 - 08:19
Can you post the XML you are using?
April 20th, 2011 - 07:57
Doh – my bad – I should have paid more attention to how you were calling the script. So the -Config parameter expects a System.Xml.XmlDocument object (or an XML string that PowerShell will convert to an XmlDocument object automatically). When using a config file like this there are several ways you can call the function:
Using the -Identity parameter as a named or positional parameter:
Deploy-SPSolution -Identity .\Solutions.xml
Deploy-SPSolution .\Solutions.xml
Using the -Config parameter as a named or positional parameter:
Deploy-SPSolution -Config (Get-Content .\Solutions.xml)
Deploy-SPSolution [xml](Get-Content .\Solutions.xml)
Sorry I didn’t notice this earlier – still a bit jet lagged I guess
April 20th, 2011 - 11:57
There’s a typo at the following row:
$solution | Install-SPSolution -GACDeployment:$($solution.ContainsGlobalAssembly) -CASPolicies:$($solution.ContainsCasPolicy) -AllWebApplication -Confirm:$false
It should be:
$solution | Install-SPSolution -GACDeployment:$($solution.ContainsGlobalAssembly) -CASPolicies:$($solution.ContainsCasPolicy) -AllWebApplications -Confirm:$false
April 20th, 2011 - 12:18
Not sure how I missed that. It’s fixed now though – thanks for the heads up!
May 12th, 2011 - 07:19
Hello Gary,
I am really looking forward to the release of the Book “Automating SharePoint 2010 with Windows PowerShell 2.0″.
Can you give a hint when to expect this treasure of knowledge in the bookshelfs?
best regards,
Andy
May 12th, 2011 - 11:18
Amazon is currently showing it as June 28th, 2011 (so just over a month from now). Wish it were sooner but that’s out of my hands
May 12th, 2011 - 11:10
I use a modified version of your previous deployment script, where the Start-SPAdminJob takes a very long time. So I’m glad you stated:
“I was using the Start-SPAdminJob cmdlet and stopping and starting the admin service – something that we shouldn’t be doing and is really just an old throwback to 2007. It’s just a bad idea – don’t do it.”
But can you explain WHY it’s a bad idea, or point me to a post where this is explained?
My current script is only tested on a (pre-production) farm with a single WFE. I want to be sure that your new deployment script runs flawlessly on a (production) farm with multiple WFE’s. Have you tested it on a multi-WFE Farm?
Thanks for sharing your good work!
Kind Regards, André
May 12th, 2011 - 11:26
There’s nothing public about why you shouldn’t use the start-spadmin cmdlet in this manner; I basically tore through what it’s doing via reflector and found some stuff that made me cringe a little. That said, essentially, this cmdlet is just for running the admin jobs when the SPAdminV4 service is stopped for security reasons and stopping and starting that service could cause issues if there are jobs that are currently being executed so, in my opinion (and that’s all this is at this point) it is safer to just leave that service alone and simply check the deployment status (the fact is you have to check the deployment status anyways in a multi-farm environment so stopping and starting the SPAdminV4 service gains you absolutely nothing (maybe you save a couple of seconds at best)).
As for using the script in production – I’ve been using the modified script for a while at my current client (not a large farm, just three servers but any more than one and it really doesn’t matter after that as the code is the same). At this particular client I have about a dozen solutions that I have been repeatedly redeploying using both parameter sets and it’s been working great for me (actually, a lot more reliable than my previous version of the script).
May 12th, 2011 - 11:57
That’s a quick reply
Thanks for sharing your reflector findings. I will leave the SPAdminV4 service alone (it will save me many minutes, at least).
Back in MOSS2007 your gl-execadmsvcjobs command helped us a lot! But it’s good to hear this part of SharePoint 2010 is improved.
Sorry, that i doubted the correct working of this revisited deployment script on a multi-WFE farm, you convinced me.
I’m going to integrate this new version in our deployment scripts.
Thanks a lot!
Kind regards, André
May 13th, 2011 - 07:37
I have a suggestion.
Name your scripts, like in the MOSS2007 days, using your initials. Like Deploy-GLSolutions(). So they stand-out from the long list of SP-commandlets and i know where to look for more info
Kind regards, André
July 12th, 2011 - 10:29
Hello Gary,
would you please tell me what result I have to expect if I am deploying a mixed amount of solutions in bulk where some have to go into the GAC and some don´t have to go into the GAC. I am asking because I ran into an error after I used bulk deployment with your script. One solution was either not properly installed in the GAC or the the equivalent of stsadm´s -copyappbincontent was not executed during script runtime. I did an upgrade to the solution with batch and stsadm which included -allowgacdeployment and -copyappbincontent and this fixed the error of the site not beeing able to display.
But I really like to use your script, I only have to know how to properly manage the above issue with mixed solutions.
Thanks a lot!
July 28th, 2011 - 08:30
The script looks at the GAC settings for the WSP so if as long as you’ve configured your WSP correctly it will GAC the resources. As far as the copyappbincontent piece goes – I don’t consider this because generally you shouldn’t be structuring your WSP in a way such that it requires it. That said, if you need it, simply add it to your script
July 29th, 2011 - 04:10
Hello Gary,
thanks for your reply. I will check the wsp´s.
And BTW, you and Shannon have done a great job with your new book! ´tis like a treasure-chest filled with great infos, especially the tips which come out of your experience and which would take a lot o´time google-ing for a solution if I would´ve run into these problems without having read your book. I´m still not completly through, but am working on it.
Thanks for sharing your knowledge!
August 19th, 2011 - 22:10
We have a Single Web application and multiple Site collection and we want to deloy the WSp in one of the Site Collection . Any help regarding this would help.
August 19th, 2011 - 23:00
Only sandboxed solutions can be deployed to a single Site Collection (the script in this post is for Farm solutions only – in my book I cover how to deploy sandboxed solutions).
September 28th, 2011 - 05:17
Hi Gary,
We were following your old script. now we want to updated with your new script.
we have.. one master script from there we are calling another PS1 scripts using Invoke-Expression.
I have created the xml and well the script which you have given,
but I m not able to debug through GUI editor.
master.ps1
Invoke-Expression “C:\Users\SPFarm\Desktop\powershell\PowerShell\Hub.Core\Deploy-SPSolutions.ps1
-Config C:\Users\SPFarm\Desktop\powershell\PowerShell\Tesco.Hub.Core\Hub.Core.xml”
your script Deploy-SPSolutions.ps1
its always tells me script is executed. xml is also not loaded.
any feedback from you?
I want to call this script from another script have to pass the xml frm master script. if the solution exists update if its a fresh solution i need to add the solution..
how can do it?
September 29th, 2011 - 12:58
Why use Invoke-Expression? Why not just load the script in memory and call the Deploy-SPSolutions function (unless you changed the script you can’t just pass in the xml to the script – it expects the function to be called).
October 21st, 2011 - 03:52
To start off, it might not be the very best practice, but we have six solutions packages, where more than one of them modifies web.config (this is unfortunate).
When we use deploy-spsolutions.ps1 with those six solutions, in a multi-farm environment, we get errors that a web config modification is already in progress when the scripts tries to deploy the second solution.
Would a workaround be to add a check for jobs named “job-webconfig-modification” in Block-SPDeployment, in addition to checking the solution’s own status?
October 21st, 2011 - 09:49
That’s how I’d do it.
December 5th, 2011 - 12:54
This is a wonderful solution Gary! This should be part of Visual Studio to build out packages for migration between environments. God bless.
December 20th, 2011 - 07:53
Hello,
I am creating msi to create Web Application on IIS and ShrePoint Farm then I will deploy the wsp to the created Site. I have used VBScript to deploy the wsp onto the Web Application. But I am not able to create a Web Application. I have a ps1 script which creates Web application, SIte Collection and Assessment Service but when I used invoke this ps1 script through msi I get compatibility issues. I was using Visual Studio setup and deployment for creating msi. Then I moved on NSIS. In this I am successfully able to run the ps1 script but it’s not creating the Web Application and Site Collection even after executing all the commands. But the Assessment service gets created which is written in the same ps1 script. I don’t know why it’s happening.
Can you suggest me how to create a Web Application and SIte Collection directly through msi.
Thanks
January 14th, 2012 - 10:36
The msi is most likely calling the x86 version of powershell and you need to make sure it calles the x64 version. Just a guess but I’d start with that.
January 9th, 2012 - 08:50
When I execute the script using xml file listing WSPs and an error occurs like so:
” ($solution.LastOperationResult -like “*Failed*”) { throw <<<< "An error occurred during the solution retraction, deployment, or update."
where can I find which specific solution has caused the error?
January 14th, 2012 - 10:21
You can add additional details to the throw message ” … $($solution.Name)”.
February 17th, 2012 - 13:21
Hi Gary – is there any reason why you do not use the -Force parameter in the Install-SPSolution calls inside your script? I’ve been using your script hundreds of times (it is awesome, thank you!), and for the first time I ran into an issue where I couldn’t deploy something and I had to add this parameter to get it to work. Is there a way to pass in the -Force parameter to your Deploy-SPSolutions commandlet for these types of edge cases?
March 9th, 2012 - 08:02
Hehe, in my version that I use I have the -Force parameter added – I just didn’t include it in the posted version. You could easily add it to the script where necessary or add it as an optional switch parameter.
July 19th, 2012 - 21:57
Hi Gary,
I just recently took some online training that you ran with Dan Holme. It was excellent. I really appreciate you sharing this script too.
Do you have any thoughts on including feature activation in a script like this? Do you intentionally keep that separate?
Lance
September 5th, 2012 - 10:46
I intentionally keep that separate because almost every build I do requires something different in terms of feature activation. I usually create a build script which will use the deploy script to deploy the WSPs and then, once deployed, do whatever additional actions are required.
September 19th, 2012 - 05:34
Hi Gary, thanks for the post, I have wsp file I want to deploy but before it i want to create a web application and a site collection, I thought to use a solution like you did, but I don’t know where to begin? do I use this code in visual studio? or is it a powershell script? where do I start?
April 9th, 2013 - 04:40
Has anyone tried to run this script with an xml config file that has a single WebApp (or more) as target? When I try to run
PS C:\temp\> Deploy-SPSolutions c:\Temp\p-solutions2.xml
where the xml-file contains
[...]
[...]
I get the errormessage:
Deploy-SPSolutions : Cannot process argument transformation on parameter ‘WebApplication’. Cannot convert the “System.Xml.XmlElement” value of type “System.Xml.XmlElement” to type “Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind[]“.
At line:98 char:85
+ Deploy-SPSolutions -Identity $path -UpgradeExisting:$upgrade -WebApplication <<<< $webApps -AllWebApplications:$(($webApps -eq $null) -or ($webApps.Length -eq 0))
+ CategoryInfo : InvalidData: (:) [Deploy-SPSolutions], ParameterBindin…mationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Deploy-SPSolutions
And I think powershell is correct! We read the web apps from the xml with
$webApps = $_.WebApplications.WebApplication
and call Deploy-SPSolutions with it,
Deploy-SPSolutions -Identity $path -UpgradeExisting:$upgrade -WebApplication $webApps -AllWe[...]
but it expects a
[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind[]]$WebApplication
as WebApplication parameter.
Any idea?
April 12th, 2013 - 10:08
Make sure you don’t have any attributes or comments or anything else for the WebApplication element. It should look just like the example in the help. If you add a comment or an attribute then PowerShell will treat it like an XmlElement and not a string which is what is needed. If you need the additional information in the XML then you’ll need to change the code so that it extracts the value out rather relying on PowerShell’s automatic type conversion.