locked
Problem running .ps1 file (whereas the command in the file work fine individually) RRS feed

  • Question

  • Hello,

    I've written the following powershell command in .ps1 file. When I execute this .ps1 file on powershell console, some of the command do not work. When I run all these commands one by one on the powershell console, they work absolutely fine.

    Has anyone faced such problem?

     Disable-SPFeature MyCustomWebPart_feature1 -url <<MyURL>>
     Disable-SPFeature MyCustomListFeature_feature1 -url <<MyURL>>
     unInstall-SPSolution –Identity MyCustomListFeature.wsp
     unInstall-SPSolution –Identity MyCustomWebPart.wsp -AllWebApplications 
     Remove-SPSolution MyCustomWebPart.wsp
     Remove-SPSolution MyCustomListFeature.wsp
     Add-SPSolution C:\TestDeploymentPackage\MyCustomListFeature.wsp
     Add-SPSolution C:\TestDeploymentPackage\MyCustomWebPart.wsp
     Install-SPSolution –Identity MyCustomListFeature.wsp -GACDeployment -Force 
     Install-SPSolution –Identity MyCustomWebPart.wsp -AllWebApplications -GACDeployment -Force
     Install-SPfeature MyCustomWebPart_feature1 -force
     Install-SPFeature MyCustomListFeature_feature1 -force
     Enable-SPFeature MyCustomListFeature_feature1 -url <<MyURL>>
     Enable-SPFeature MyCustomWebPart_feature1 -url <<MyURL>>
    
    

     

    Thanks,
    Ajit

    • Moved by Cathy Kong Wednesday, December 15, 2010 8:21 AM (From:Team Foundation Server - Build Automation)
    Tuesday, December 14, 2010 11:38 AM

Answers

  • I faced the same problem. The problem is that some (all?) of these commands become (scheduled) jobs in SharePoint. In your script, you don't listen to a certain job-timer and wait for it to finish, you directly start a new command (job) and presume the previous one has done its work. That's the reason this works when you enter all the lines manually: you give each job more time to finish. :)

    This script will search for .wsp files, uninstalls them when they're already deployed and then deploys them. It also waits for the jobtimer.
    John's suggestion works most of the time, but has the drawback that it really slows down the whole script (while not every command needs the whole 60 second timespan) and it's still not sure if a job has finished by that time.

    This script uses a fixed your_site string, you should replace this with your own site or even better, make it a parameter. Furthermore, it asumes the name of the feature ends with _Feature1, which isn't a nice solution.

     

    Param($Param1)
    Clear-Host
    
    # Wait for the SharePoint timer job name that contains "solution-deployment".
    function Wait4TimerRetract
    { 
     Write-Host -NoNewLine "Finding timer job"
     # The language-dependent display name of the timer job contains "Solution Retraction". 
     while (($jd = Get-SPTimerJob | ?{ $_.DisplayName -like "*Solution Retraction*"+$fileName+"*" }) -eq $null)
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     $jdName = $jd.Name
     Write-Host ("`njob: " + $jd.DisplayName)
     Write-Host -NoNewLine Waiting to finish
     
     while ((Get-SPTimerJob $jdName) -ne $null) 
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     
     Write-Host
     $jd.HistoryEntries | %{ Write-Host job history: $_.Status }
     Write-Host
    } # End of function Wait4Timer.
    
    function Wait4TimerDeploy
    { 
     Write-Host -NoNewLine "Finding timer job"
     # The language-dependent display name of the timer job contains "Solution Retraction". 
     while (($jd = Get-SPTimerJob | ?{ $_.Name -like "*solution-deployment*" + $fileName + "*" }) -eq $null) 
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     $jdName = $jd.Name
     Write-Host ("`njob: " + $jd.DisplayName)
     Write-Host -NoNewLine Waiting to finish
     
     while ((Get-SPTimerJob $jdName) -ne $null) 
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     
     Write-Host
     $jd.HistoryEntries | %{ Write-Host job history: $_.Status }
     Write-Host
    } # End of function Wait4Timer.
    
    
    $snapin = Get-PSSnapin | where-object {$_.Name -eq 'Microsoft.SharePoint.PowerShell'}
    if ($snapin -eq $null)
    {
     echo ('Add SharePoint.PowerShell SnapIn...')
     Add-PSSnapin Microsoft.SharePoint.PowerShell
    }
    
    
    if ($Param1 -eq $null)
    {
     $Param1 = '*.wsp'
    }
    
    Foreach ($file in Get-Childitem $Param1)
    {
     $filename = $file.name
    
     $SolutionPackageName = $file.name
     $solution = Get-SPSolution | where-object {$_.Name -eq $SolutionPackageName}
     $feature = $file.name.Replace(".wsp", "_Feature1")
    
     # check to see if solution package has been installed
     if ($solution -ne $null) 
     {
      # check to see if solution package is currently deployed
      if($solution.Deployed -eq $true)
      {
    	echo ('Uninstall ' + $file.name)
    	echo ''
    
      echo 'Disable feature...'
      Disable-SPFeature -Identity $feature -url http://your_site -Verbose -Confirm:$false
      echo ''
      echo 'Uninstall solution...'
      Uninstall-SPSolution -Identity $SolutionPackageName -WebApplication http://your_site -Verbose -Confirm:$false
      echo ''
    	Wait4TimerRetract
      echo 'Remove solution...'
      Remove-SPSolution –Identity $SolutionPackageName -Verbose -Confirm:$false
     	echo ''
    	echo ('Uninstall ' + $file.name + ' done.')
    
      }
     }
     echo ''
    
     echo ('Add solution ' + $file.name)
     Add-SPSolution $file.fullname 
     echo ''
     echo 'Install solution...'
     Install-SPSolution -Identity $SolutionPackageName -WebApplication http://your_site -GACDeployment -Verbose
     echo ''
     Wait4TimerDeploy
     echo ''
     echo ('Enable feature ' + $feature + '...')
     Enable-SPFeature -Identity $feature -url http://your_site -Verbose
     echo ''
     echo ('Done installing ' + $file.name + '.')
     echo ''
    
    } 
    

     

     

    • Proposed as answer by Michiel van Erp Wednesday, December 15, 2010 3:50 PM
    • Edited by Michiel van Erp Thursday, December 16, 2010 9:31 AM cleaned script
    • Marked as answer by Mervyn Zhang Monday, December 20, 2010 10:32 AM
    Wednesday, December 15, 2010 3:48 PM
  • If you need to add a sleep try this after each line (probably overkill but you can adjust it until Michiel comes back to you)

    Start-Sleep -seconds 60

    J

    • Marked as answer by Mervyn Zhang Monday, December 20, 2010 10:32 AM
    Wednesday, December 15, 2010 4:35 PM
  • Might want to consider running them as backgroud jobs (using start-job), an then you can use wait-job to insure the each step completes before starting the next one.
    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    • Marked as answer by Mervyn Zhang Monday, December 20, 2010 10:32 AM
    Thursday, December 16, 2010 4:18 AM

All replies

  • Hi Ajit,

    Thanks for posting your question.

    I am moving this thread from "Team Foundation Server-Build Automation" forum to "Windows Server Forum> Windows Powershell " forum, since the issue is more related to Powershell. There are more powershell experts in that forum and your question will get a quicker response.


    Cathy Kong [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, December 15, 2010 8:25 AM
  • Hi,

    Is it the same commands which don't run each time? Do you know which ones don't run? Do you get any error messages on screen on in the event log?

    J

    Wednesday, December 15, 2010 9:09 AM
  • I faced the same problem. The problem is that some (all?) of these commands become (scheduled) jobs in SharePoint. In your script, you don't listen to a certain job-timer and wait for it to finish, you directly start a new command (job) and presume the previous one has done its work. That's the reason this works when you enter all the lines manually: you give each job more time to finish. :)

    This script will search for .wsp files, uninstalls them when they're already deployed and then deploys them. It also waits for the jobtimer.
    John's suggestion works most of the time, but has the drawback that it really slows down the whole script (while not every command needs the whole 60 second timespan) and it's still not sure if a job has finished by that time.

    This script uses a fixed your_site string, you should replace this with your own site or even better, make it a parameter. Furthermore, it asumes the name of the feature ends with _Feature1, which isn't a nice solution.

     

    Param($Param1)
    Clear-Host
    
    # Wait for the SharePoint timer job name that contains "solution-deployment".
    function Wait4TimerRetract
    { 
     Write-Host -NoNewLine "Finding timer job"
     # The language-dependent display name of the timer job contains "Solution Retraction". 
     while (($jd = Get-SPTimerJob | ?{ $_.DisplayName -like "*Solution Retraction*"+$fileName+"*" }) -eq $null)
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     $jdName = $jd.Name
     Write-Host ("`njob: " + $jd.DisplayName)
     Write-Host -NoNewLine Waiting to finish
     
     while ((Get-SPTimerJob $jdName) -ne $null) 
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     
     Write-Host
     $jd.HistoryEntries | %{ Write-Host job history: $_.Status }
     Write-Host
    } # End of function Wait4Timer.
    
    function Wait4TimerDeploy
    { 
     Write-Host -NoNewLine "Finding timer job"
     # The language-dependent display name of the timer job contains "Solution Retraction". 
     while (($jd = Get-SPTimerJob | ?{ $_.Name -like "*solution-deployment*" + $fileName + "*" }) -eq $null) 
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     $jdName = $jd.Name
     Write-Host ("`njob: " + $jd.DisplayName)
     Write-Host -NoNewLine Waiting to finish
     
     while ((Get-SPTimerJob $jdName) -ne $null) 
     {
      Write-Host -NoNewLine .
      Start-Sleep -Seconds 1
     }
     
     Write-Host
     $jd.HistoryEntries | %{ Write-Host job history: $_.Status }
     Write-Host
    } # End of function Wait4Timer.
    
    
    $snapin = Get-PSSnapin | where-object {$_.Name -eq 'Microsoft.SharePoint.PowerShell'}
    if ($snapin -eq $null)
    {
     echo ('Add SharePoint.PowerShell SnapIn...')
     Add-PSSnapin Microsoft.SharePoint.PowerShell
    }
    
    
    if ($Param1 -eq $null)
    {
     $Param1 = '*.wsp'
    }
    
    Foreach ($file in Get-Childitem $Param1)
    {
     $filename = $file.name
    
     $SolutionPackageName = $file.name
     $solution = Get-SPSolution | where-object {$_.Name -eq $SolutionPackageName}
     $feature = $file.name.Replace(".wsp", "_Feature1")
    
     # check to see if solution package has been installed
     if ($solution -ne $null) 
     {
      # check to see if solution package is currently deployed
      if($solution.Deployed -eq $true)
      {
    	echo ('Uninstall ' + $file.name)
    	echo ''
    
      echo 'Disable feature...'
      Disable-SPFeature -Identity $feature -url http://your_site -Verbose -Confirm:$false
      echo ''
      echo 'Uninstall solution...'
      Uninstall-SPSolution -Identity $SolutionPackageName -WebApplication http://your_site -Verbose -Confirm:$false
      echo ''
    	Wait4TimerRetract
      echo 'Remove solution...'
      Remove-SPSolution –Identity $SolutionPackageName -Verbose -Confirm:$false
     	echo ''
    	echo ('Uninstall ' + $file.name + ' done.')
    
      }
     }
     echo ''
    
     echo ('Add solution ' + $file.name)
     Add-SPSolution $file.fullname 
     echo ''
     echo 'Install solution...'
     Install-SPSolution -Identity $SolutionPackageName -WebApplication http://your_site -GACDeployment -Verbose
     echo ''
     Wait4TimerDeploy
     echo ''
     echo ('Enable feature ' + $feature + '...')
     Enable-SPFeature -Identity $feature -url http://your_site -Verbose
     echo ''
     echo ('Done installing ' + $file.name + '.')
     echo ''
    
    } 
    

     

     

    • Proposed as answer by Michiel van Erp Wednesday, December 15, 2010 3:50 PM
    • Edited by Michiel van Erp Thursday, December 16, 2010 9:31 AM cleaned script
    • Marked as answer by Mervyn Zhang Monday, December 20, 2010 10:32 AM
    Wednesday, December 15, 2010 3:48 PM
  • If you need to add a sleep try this after each line (probably overkill but you can adjust it until Michiel comes back to you)

    Start-Sleep -seconds 60

    J

    • Marked as answer by Mervyn Zhang Monday, December 20, 2010 10:32 AM
    Wednesday, December 15, 2010 4:35 PM
  • I'll try your solution, John. It seems to me that few powershell commands like unistall-spsolution, install-spsolution are async calls so before the uninstall finishes its work, the script has already executed the install statement because the following error which I get, seems to suggest that:

    Install-SPSolution : A deployment or retraction is already under way for the solution "mycustomwebpart.wsp", and only one deployment or retraction at a time is supported.

    I'll inform you if the start-sleep solution works

    Thursday, December 16, 2010 3:59 AM
  • Might want to consider running them as backgroud jobs (using start-job), an then you can use wait-job to insure the each step completes before starting the next one.
    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    • Marked as answer by Mervyn Zhang Monday, December 20, 2010 10:32 AM
    Thursday, December 16, 2010 4:18 AM