Tuesday 12 January 2016

Powershell Workflow: Install Powershell Vesrion 4 and Import SQLPS module

I had a requirement to collect the required site and list details from SharePoint sites and storing in SQL database. I have developed Powershell scripts and Powershell Workflows(for Multiple threading) to get the better Performance and then to reduce execution time.

In my environment Powershell Version 3.0 has installed already in the Server. I implemented powershell workflow scripts  as below,

GetSubSites.PS1 (Main script file calls other child PS1 files)

Add-PsSnapin Microsoft.SharePoint.PowerShell

## SharePoint DLL

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")




$serverName="DEFxxxx"

$databaseName="SharePointAdminDB"

$invocation = (Get-Variable MyInvocation).Value

$directorypath = Split-Path $invocation.MyCommand.Path




function Main {




param
(
[parameter(mandatory=$true)][string]$serverName,

[parameter(mandatory=$true)][string]$databaseName,

[parameter(mandatory=$true)][string]$WebApplicationUrl



)


$webApp = Get-SPWebApplication $webApplicationURL

foreach($site in $webApp.Sites)



{
foreach($subWeb in $site.AllWebs)



{
IterateSubSites($subWeb)




$SelectSQLCmd="Select COUNT(*) as _count from SPSITES where WebapplicationUrl='"+$webApplicationURL+"' and SitecollectionUrl='"+$site.Url+"' and SubSiteUrl='"+$subWeb.Url+"'";




$recordExists = Invoke-Sqlcmd -ServerInstance $serverName -Database $databaseName -Query $SelectSQLCmd




if($recordExists._count -gt 0)



{


$SQLCmd="UPDATE SPSITES SET WebapplicationUrl='"+$webApplicationURL+"' where WebapplicationUrl='"+$webApplicationURL+"' and SitecollectionUrl='"+$site.Url+"' and SubSiteUrl='"+$subWeb.Url+"'";

Invoke-Sqlcmd -ServerInstance $serverName -Database $databaseName -Query $SQLCmd




"Update: Site URL - "+$subWeb.Url



}
else



{
$SQLCmd="INSERT INTO SPSITES (WebapplicationUrl, SitecollectionUrl, SubSiteUrl) VALUES ('" + $webApplicationURL + "','"+$site.Url+"','"+$subWeb.Url+"')"

Invoke-Sqlcmd -ServerInstance $serverName -Database $databaseName -Query $SQLCmd

"Insert: Site URL - "+ $subWeb.Url



}



}
$subWeb.Dispose()



}
$site.Dispose()



}


#Recursive function iterates all subsites

function IterateSubSites ([Microsoft.SharePoint.SPWeb]$subSite)



{
if ($subSite -ne $null)



{
if($subSite.Webs -ne $null)



{
foreach($subsites in $subSite.Webs)



{
IterateSubSites($subsites)



}

}

}

}


#Get all webapplications from SPWebapplications sql table
function GetAllWebApplicationsFromTable {




param
(
[parameter(mandatory=$true)][string]$serverName,

[parameter(mandatory=$true)][string]$databaseName,

[parameter(mandatory=$true)][string]$SPFarmName,

[parameter(mandatory=$true)][string]$SQLCmd



)
$DBConnectionString = "Data Source=$serverName; Initial Catalog=$databaseName; Integrated Security=SSPI"

$conn = New-Object System.Data.SqlClient.SqlConnection($DBConnectionString)

$conn.Open()

$cmd = new-object system.data.sqlclient.sqlcommand($SQLCmd,$conn)

$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $cmd

$dsSites = New-Object System.Data.DataSet

$adapter.Fill($dsSites) | Out-Null

$conn.Close()

if($dsSites.Tables[0].rows.count -gt 0)



{
$ret=$dsSites.Tables[0]

foreach ($set in $ret)



{
$webAppUrl = $set.WebapplicationUrl




Main $serverName $databaseName $webAppUrl



}

}

}

 

 
Start-Transcript

Set-ExecutionPolicy Unrestricted




#get Farm Name and match with SQL records get webapplication urls
$SPFarm = Get-spfarm

$SPFarmName = $SPFarm.Name




#Iterate all site collections and sub sites, store in SPSITES table
GetAllWebApplicationsFromTable $serverName $databaseName $SPFarmName "select * from SPWebApplications where FarmName='$SPFarmName'"




#Iterate all list details and store in SPLISTS table
."$directorypath\GetListDetails.ps1" $serverName $databaseName




#Iterate all list details and store in SPSiteCollectionDetails table
."$directorypath\GetSiteCollectionDetails.ps1" $serverName $databaseName




#Iterate all list workflow details and store in SPListWorkflowDetails table
."$directorypath\GetListWorkflowDetails.ps1" $serverName $databaseName




#Iterate all list workflow details and store in SPListWorkflowDetails table
."$directorypath\GetSiteGroupsandUsers.ps1" $serverName $databaseName




While executing the PowerShell  scripts it throws the Out of memory exception error because of the default memory size(MaxMemoryPerShellMB) is 150MB. 

I have increased the default memory(MaxMemoryPerShellMB) to 4GB,


However  Windows Remote Management (WinRM) service does not use the customized value of the MaxMemoryPerShellMB quota. Instead, the WinRM service uses the default value, which is 150 MB.



None of above is worked for me. So finally i have installed Powershell Version 4.0 and then installed required Features back for using Invoke SQL commands in the powershell window.

You can install Powershell Version 4.0(x64 or x86) and restart the Server,
https://www.microsoft.com/en-us/download/details.aspx?id=40855

To run invoke-sqlcmd, the below three files are required,
Microsoft® Windows PowerShell Extensions for SQL Server® 2012
Microsoft® SQL Server® 2012 Shared Management Objects
Microsoft® System CLR Types for SQL Server® 2012

https://www.microsoft.com/en-us/download/details.aspx?id=29065

 Then navigate to "C:\Program Files\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLPS"

run .\SQLPS.PS1 file in SharePoint powershell window

Execute Import-Module SQLPS

At last i can able to execute SQL commands in the powershell Version 4.0
 

No comments:

Post a Comment