Exportálja a SharePoint-listaadatokat SQL Server Table-ba a PowerShell segítségével
Követelmény: Exportálja a SharePoint-listaadatokat SQL Server táblába.
Egy házon belül épített üzleti intelligencia eszköz esetében megköveteltük, hogy a SharePoint lista adatait exportáljuk egy SQL Server táblába. Mivel a SharePoint tartalomadatbázisok közvetlen lekérdezését a Microsoft nem támogatja, ez teljesítményproblémákat is okozhat a SharePoint farmon - ne gondoljunk tovább! Természetesen a piacon harmadik féltől származó termékek is elérhetők erre. A PowerShell azonban használható ennek a követelménynek a teljesítésére.
Ez a PowerShell-szkript lekéri az adott SharePoint-listát/-listákat, végigfut az összes elérhető mezőn, dinamikusan létrehoz egy SQL Server táblát, majd a fordítás után beszúrja az adatokat, és beszúrja az SQL Server adatbázistáblájába.
Íme a PowerShell-szkriptem, amellyel a SharePoint-listát SQL Server táblává konvertálhatom, és adatokat vonhatok ki a SharePointból SQL-be:
PowerShell-szkript a SharePoint-listaadatok SQL Server táblába való kivonásához:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
Function Create-List2Table($ListName,$TableName, $WebURL)
{
#Configuration Variables
$DatabaseServer="SP16-SQLServer01"
$DatabaseName="SharePointBI"
#SQL Authentication
$UserID="UserID"
$Password="Password"
#Log File
$CurrentDir=Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
$LogFile = $CurrentDir+ "\" + $(Get-Date -format "yyyyMMdd_hhmmss")+".txt"
#Get Web, List and Fields
$Web= Get-SPWeb $WebURL
$List= $Web.Lists[$ListName]
#Get all required fields from the lists
$ListFields = $List.Fields | Where { ($_.Hidden -ne $true ) -and ($_.ReadOnlyField -ne $true ) -and ($_.InternalName -ne "Attachments") -and ($_.InternalName -ne "ContentType") }
#Function to Execute given SQL Query
Function Execute-SQLQuery([string]$Query)
{
#Write-Host "Executing SQL: ", $Query
#Connection object
$Connection = New-Object System.Data.SqlClient.SqlConnection("server=$DatabaseServer;database=$DatabaseName;User Id=$UserID;Password=$Password")
try
{
$Connection.open()
$cmd = new-object System.Data.SqlClient.SqlCommand ($Query, $Connection)
$ReturnValue = $cmd.ExecuteNonQuery()
}
catch { Write-Host "Error: ", $error[0]; "$($Query): $($_.Exception.Message)" >> $LogFile }
finally{ $Connection.close() }
}
#Function to Drop Table, if exists!
Function Drop-Table([string]$TableName)
{
$Query = "IF (OBJECT_ID('[dbo].[$($TableName)]','U') IS NOT NULL) DROP TABLE [dbo].[$($TableName)]"
#Run the Query
Execute-SQLQuery $Query
}
#Get SQL column Definition for SharePoint List Field
Function Get-ColumnDefinition([Microsoft.SharePoint.SPField]$Field)
{
$ColumnDefinition=[string]::Empty
Switch($Field.Type)
{
"Boolean" { $ColumnDefinition = '['+ $Field.InternalName +'] [bit] NULL '}
"Choice" { $ColumnDefinition = '['+ $Field.InternalName +'] [nvarchar](MAX) NULL '}
"Currency" { $ColumnDefinition = '['+ $Field.InternalName +'] [decimal](18, 2) NULL '}
"DateTime" { $ColumnDefinition = '['+ $Field.InternalName +'] [datetime] NULL '}
"Guid" { $ColumnDefinition = '['+ $Field.InternalName +'] [uniqueidentifier] NULL '}
"Integer" { $ColumnDefinition = '['+ $Field.InternalName +'] [int] NULL '}
"Lookup" { $ColumnDefinition = '['+ $Field.InternalName +'] [nvarchar] (500) NULL '}
"MultiChoice" { $ColumnDefinition = '['+ $Field.InternalName +'] [nText] (MAX) NULL '}
"Note" { $ColumnDefinition = '['+ $Field.InternalName +'] [nText] NULL '}
"Number" { $ColumnDefinition = '['+ $Field.InternalName +'] [decimal](18, 2) NULL '}
"Text" { $ColumnDefinition = '['+ $Field.InternalName +'] [nVarchar] (MAX) NULL '}
"URL" { $ColumnDefinition = '['+ $Field.InternalName +'] [nvarchar] (500) NULL '}
"User" { $ColumnDefinition = '['+ $Field.InternalName +'] [nvarchar] (255) NULL '}
default { $ColumnDefinition = '['+ $Field.InternalName +'] [nvarchar] (MAX) NULL '}
}
return $ColumnDefinition
}
################ Format Column Value Functions ######################
Function Format-UserValue([object] $ValueToFormat)
{
$Users = [string]::join("; ",( $ValueToFormat | Select -expandproperty LookupValue))
$Users = $Users -replace "'", "''"
return "'" + $Users + "'"
}
Function Format-LookupValue([Microsoft.SharePoint.SPFieldLookupValueCollection] $ValueToFormat)
{
$LookupValue = [string]::join("; ",( $ValueToFormat | Select -expandproperty LookupValue))
$LookupValue = $LookupValue -replace "'", "''"
return "'" + $LookupValue + "'"
}
Function Format-DateValue([string]$ValueToFormat)
{
[datetime] $dt = $ValueToFormat
return "'" + $dt.ToString("yyyyMMdd HH:MM:ss") + "'"
}
Function Format-MMSValue([Object]$ValueToFormat)
{
return "'" + $ValueToFormat.Label + "'"
}
Function Format-BooleanValue([string]$ValueToFormat)
{
if($ValueToFormat -eq "Yes") {return 1} else { return 0}
}
Function Format-StringValue([object]$ValueToFormat)
{
[string]$result = $ValueToFormat -replace "'", "''"
return "'" + $result + "'"
}
#Function to get the value of given field of the List item
Function Get-ColumnValue([Microsoft.SharePoint.SPListItem] $ListItem, [Microsoft.SharePoint.SPField]$Field)
{
$FieldValue= $ListItem[$Field.InternalName]
#Check for NULL
if([string]::IsNullOrEmpty($FieldValue)) { return 'NULL'}
$FormattedValue = [string]::Empty
Switch($Field.Type)
{
"Boolean" {$FormattedValue = Format-BooleanValue($FieldValue)}
"Choice" {$FormattedValue = Format-StringValue($FieldValue)}
"Currency" {$FormattedValue = $FieldValue}
"DateTime" {$FormattedValue = Format-DateValue($FieldValue)}
"Guid" { $FormattedValue = Format-StringValue($FieldValue)}
"Integer" {$FormattedValue = $FieldValue}
"Lookup" {$FormattedValue = Format-LookupValue($FieldValue) }
"MultiChoice" {$FormattedValue = Format-StringValue($FieldValue)}
"Note" {$FormattedValue = Format-StringValue($Field.GetFieldValueAsText($ListItem[$Field.InternalName]))}
"Number" {$FormattedValue = $FieldValue}
"Text" {$FormattedValue = Format-StringValue($Field.GetFieldValueAsText($ListItem[$Field.InternalName]))}
"URL" {$FormattedValue = Format-StringValue($FieldValue)}
"User" {$FormattedValue = Format-UserValue($FieldValue) }
#Check MMS Field
"Invalid" { if($Field.TypeDisplayName -eq "Managed Metadata") { $FormattedValue = Format-MMSValue($FieldValue) } else { $FormattedValue =Format-StringValue($FieldValue)} }
default {$FormattedValue = Format-StringValue($FieldValue)}
}
Return $FormattedValue
}
#Create SQL Server table for SharePoint List
Function Create-Table([Microsoft.SharePoint.SPList]$List)
{
#Check if the table exists already
$Query="CREATE TABLE [dbo].[$($TableName)]([ID] [int] NOT NULL PRIMARY KEY, "
foreach ($Field in $ListFields)
{
$Query += Get-ColumnDefinition($Field)
$Query += ","
}
$Query += ")"
#Run the Query
Execute-SQLQuery $Query
}
#Insert Data from SharePoint List to SQL Table
Function Insert-Data([Microsoft.SharePoint.SPList]$List)
{
#Iterate through each row from the list
$ListItems= $List.Items # | where {$_["ID"] -eq 820}
#Progress bar counter
$Counter=0
$ListItemCount=$ListItems.Count
Write-host "Total SharePoint List Items to Copy:" $ListItemCount
foreach ($Item in $ListItems)
{
Write-Progress -Activity "Copying SharePoint List Items. Please wait...`n`n" -status "Processing List Item: $($Item['ID'])" -percentComplete ($Counter/$ListItemCount*100)
$sql = new-object System.Text.StringBuilder
[void]$sql.Append("INSERT INTO [dbo].[$($TableName)] ( [ID] ")
$vals = new-object System.Text.StringBuilder
[void]$vals.Append("VALUES ("+ $Item["ID"])
foreach ($Field in $ListFields)
{
[void]$sql.Append(",[$($Field.InternalName)]")
$ColumnValue = Get-ColumnValue $Item $Field
[void]$vals.Append( ","+ $ColumnValue)
}
[void]$sql.Append(") ")
[void]$vals.Append(") ")
#Combine Field and Values
$SQLStatement = $sql.ToString() + $vals.ToString()
#Run the Query
Execute-SQLQuery $SQLStatement
$Counter=$Counter+1;
}
"Total SharePoint List Items Copied: $($ListItemCount)" >> $LogFile
}
#Call functions to export-import SharePoint list to SQL table
Drop-Table $TableName
Create-Table $List
Insert-Data $List
}
#Call the function to Create SQL Server Table from SharePoint List
Create-List2Table -ListName "Projects" -TableName "ProjectData" -WebURL "https://portal.crescent.com/projects"
#Create-List2Table -ListName "Documents" -TableName "Documents" -WebURL "https://portal.crescent.com"
A szkript futtatása előtt győződjön meg arról, hogy létrehozta az adatbázist (az én esetemben ez „SharePointBI”), és a szkriptben megadott felhasználónév DBO vagy hasonló hozzáféréssel rendelkezik az adatbázishoz.
