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.
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
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