2

While working on a SharePoint 2010 solution in Visual Studio 2012, I want to run a PowerShell script to remove a lookup field from one of my lists, allowing Visual Studio to automatically resolve the script deployment conflict by deleting the existing list and replacing it with the one in my solution.

However, when running PowerShell from the project's "Pre-deployment Command Line" in Visual Studio, when my script attempts to use get-spweb, PowerShell reports that the object is not found. Scrolling upward in the Visual Studio's output window, I see that Add-PsSnapin Microsoft.SharePoint.PowerShell is reporting various problems:

(Note: actual error message has the expanded $(ProjectDir) value rather than "$(ProjectDir)" as text. Trying various levels of indirection to ensure I'm using the correct, 64-bit version of PowerShell does not change this working directory, nor does using cd or set-location commands prior to calling my script make any difference in this directory. I'm wondering if an invalid working directory is part of the problem...)

The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.
Could not read the XML Configuration file in the folder CONFIG\PowerShell\Registration\.
Could not find a part of the path '$(ProjectDir)\CONFIG\PowerShell\Registration'.
No xml configuration files loaded.
Unable to register core product cmdlets.
Could not read the Types files in the folder CONFIG\PowerShell\types\.
Could not find a part of the path '$(ProjectDir)\CONFIG\PowerShell\types'.
"No Types files Found."
Could not read the Format file in the folder CONFIG\PowerShell\format\.
Could not find a part of the path '$(ProjectDir)\CONFIG\PowerShell\format'.
No Format files Found.

Running the PowerShell script directly from a Command Prompt window works fine, the SharePoint snapin loads correctly, but running from Visual Studio always fails. Previous research indicated potential problems with SharePoint and SQL Server permissions, yet my account has full admin in both. Visual Studio is running "as administrator". Research also turned up possible problems with 32-bit vs 64-bit. My Pre-deployment Command Line now calls %comspec% /c to ensure 64-bit.

Pre-deployment Command Line:

%comspec% /c ""$(ProjectDir)PowerShell Scripts\predeployment-command.cmd" "$(SharePointSiteUrl)" "$(ConfigurationName)" "$(ProjectDir)""

*.cmd file:

echo off
rem pre-deployment script
rem call from pre-deployment command line like
rem      %comspec% /c ""$(ProjectDir)PowerShell Scripts\predeployment-command.cmd "$(SharePointSiteUrl)" "$(ConfigurationName)" "$(ProjectDir)""
rem 
echo Running "predeployment-command.cmd" file
echo
echo %%1 = %~1
echo %%2 = %~2
echo %%3 = %~3
echo
cd "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14"
cd
echo on
powershell.exe -file "%~3PowerShell Scripts\predeployment-script.ps1" -targetWeb "%~1" -CONFIG "%~2"

PowerShell script file:

<#
.SYNOPSIS
    Pre-deployment script for Visual Studio development deployments
    add command to run this script in the project's pre-deployment command-line box

.EXAMPLE
    powershell .\dev-predeployment-script.ps1
#>
param(

   [string] $targetWeb = $(throw "Please specify the site to which Visual Studio is deploying!"),

   [string] $CONFIG = $(throw "Please specify the active configuration!")

   )
write-host "Running Pre-Deployment PowerShell Script";

# Ensure SharePoint extensions are loaded
$snapin = $(Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction "SilentlyContinue");
if($snapin -eq $null) {
    Add-PsSnapin Microsoft.SharePoint.PowerShell;
}

$ErrorActionPreference = 'Stop';

#echo back parameter values:
write-host "TargetWeb = $targetWeb"
write-host "Configuration = $CONFIG"

#get web-site
$web = get-spweb $targetWeb;

if($web -ne $null) {
    $recipients = $web.lists["Recipients"];

    if($recipients -ne $null) {
        $lookupField = $recipients.Fields["Request ID"];

        if($lookupField -ne $null) {
            $recipients.fields.remove($lookupField);
        }
    }
}

I'm developing on a 64-bit Windows Server 2008 r2 virtual machine.

Zarepheth
  • 2,465
  • 2
  • 32
  • 49
  • Have you looked at http://www.thesharepointbaker.co.uk/2011/12/post-deployment-powershell-sharepoint-visual-studio/ ? – Eris Jul 18 '13 at 23:55
  • @Eris Yes, I've looked at that article and attempted to use the author's recommendations when working on a 64-bit system. The problem still occurs, it appears that `Add-PsSnapin Microsoft.SharePoint.PowerShell;` is failing. Adding that snapin is the source of all the warnings in my first code block, above. Note, the command works fine if running PowerShell from a Windows Command Prompt window or one of the PowerShell utilities - it just fails when run in VS from a SharePoint project's pre-deployment command line box. – Zarepheth Jul 20 '13 at 18:05
  • Have you also tried running Powershell as administrator? What about this other blog that says it works with a second layer of indirection? http://blogs.msdn.com/b/jorman/archive/2011/04/12/add-pssnapin-microsoft-sharepoint-powershell-failing-after-sharepoint-install.aspx – Eris Jul 20 '13 at 22:37
  • I've configured my Development VM to run most things as administrator - especially the command line, powershell, powershell ISE, and Visual Studio. So lack of Admin privileges, at least in the process that starts powershell, cannot be the issue. My use of a *.cmd file was an attempt at redirection, but I'll give your suggestion a shot. Maybe using PowerShell for the indirection instead of command.com will be more successful. – Zarepheth Jul 22 '13 at 13:20
  • Additional redirection did not fix the problem... :( My PowerShell script still encounters the same errors when attempting to load the Microsoft.SharePoint.PowerShell snapin. It seems that it is trying to read from the "\CONFIG\..." directories starting from my project's directory rather than the proper location in the Windows directory. And this happens regardless of my level of indirection and whether or not I've used any `cd` or `set-location` commands prior to calling `add-snapin`. – Zarepheth Jul 23 '13 at 14:13
  • Try adding `-version 2` to your powershell line(s). This would force powershell to load as V2 instead of V3 which I've also read causes problems with SP2010 – Eris Jul 23 '13 at 17:42
  • Adding `-version 2` to both the initial and indirect powershell.exe calls did not make a difference. – Zarepheth Jul 26 '13 at 13:04
  • I followed the suggestions from http://blogs.msdn.com/b/jorman/archive/2011/04/12/add-pssnapin-microsoft-sharepoint-powershell-failing-after-sharepoint-install.aspx for the indirection. In the sample code is a `Start-Process` command with a `-WorkingDirectory $path` parameter. The `$path` variable is not explicitly set within the sample code, so I added this line `$path = 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14';` just before the `Start-Process command`. That also did nothing - I'm still getting the same snapin warnings on the same paths. – Zarepheth Jul 26 '13 at 13:09
  • As a workaround, I hard-coded the lookup field removal in the feature deactivated event. This enabled Visual Studio to automatically resolve deployment conflicts by deleting the lists. More recent development on this project has stripped out the lookup columns so they are no longer an issue. – Zarepheth Sep 19 '13 at 15:51

1 Answers1

0

Hi I know this was from a billion years ago, but I just struggled with and solved the same problem, so posting here in case others run into it.

Two problems are happening and fighting with each other:

  1. Problem #01: Spaces in paths: At first glance I see a lot of 'em.
    Make your life easier and get rid of these (if/when possible).

    Examples:

    "$(ProjectDir)PowerShell Scripts"
    "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14"
    "$(SharePointSiteUrl)" "$(ConfigurationName)" "$(ProjectDir)" <-- This is the problem!!!
    maybe others too? you've got multiple levels there that's hard to visualize.

    Call chain is (I think?):

    • LVL1: %comspec% /c
    • LVL2: predeployment-command.cmd
    • LVL3: "%~3PowerShell Scripts\predeployment-script.ps1"
      which you wish to be: '$(ProjectDir)PowerShell Scripts\predeployment-script.ps1'
      but is likely rendering as: 'path with spaces"PowerShell Scripts\predeployment-script.ps1'
  2. Problem #02: Visual Studio Paths always end in backslash "\" (which I hilariously have to escape so that the SO Markdown will display it). BATCH Expansion Escapes the next character. So if you've correctly wrapped quotes around a "path with spaces", but the "path with spaces ends in backslash\", then you end up with "...\" being escaped to %path%" with a trailing or hanging quote " at the end

Visual Studio $(ProjectDir) - with spaces!

  1. if you DO NOT include the quotes, then spaces in path will break it. if you DO include quotes then it gets escaped.
  2. Solution is to include an extra slash at the end, resulting in double backslash \\ which escapes down to single backslash '\'... whew!
    Here's my working version if you'd like an example to work off of:
    https://stackoverflow.com/a/73409081/738895

Final note: IF all you need is to ensure (32-bit vs 64-bit), this can be done via the Configuration Manager in Visual Studio
Configuration Manager in Visual Studio

You can google "Visual Studio force build as x86" if you need via msbuild/commandline or follow these instructions https://learn.microsoft.com/en-us/visualstudio/ide/how-to-configure-projects-to-target-platforms?view=vs-2022 Microsoft Select Configuration x86 Version

m1m1k
  • 1,375
  • 13
  • 14