Use PowerShell to get all your SQL databases and their size

Quick script to get all the databases on a server, then output to a CSV file.

In this example, all I needed was the database name and its size.

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server') "YourSQLServer"
$dbs=$s.Databases
$dbs | SELECT Name, Size | Export-Csv c:\test.txt

Other properties:

$dbs | SELECT Name, Collation, CompatibilityLevel, AutoShrink, RecoveryModel, Size, SpaceAvailable

Credit for the base script:
Edwin M Sarmiento

Use PowerShell to add Holidays to Outlook Calendar

Geeking around with PowerShell today trying to add all company holidays to my Outlook calendar. In the script, I’m creating all day appointments and setting the Show As to out of office. Simple enough!

function get-mailfolders { 
	$outlookfolders = @() 
	$outlook = New-Object -ComObject Outlook.Application 
	foreach ($folder in $outlook.Session.Folders){ 

		foreach($mailfolder in $folder.Folders ) { 
			$olkf = New-Object PSObject -Property @{ 
				Path = $($mailfolder.FullFolderPath) 
				EntryID = $($mailfolder.EntryID) 
				StoreID = $($mailfolder.StoreID) 
			} 

			$outlookfolders += $olkf 
		} 
	} 
	$outlookfolders 
}

$outlook = new-object -com Outlook.Application
$folder = get-mailfolders | where {$_.Path -like "*calendar*" -and $_.Path -and $_.Path -like "*$mailbox*"} 
$calendar = $outlook.Session.GetFolderFromID($folder.EntryID, $folder.StoreID) 

$holidays = @{"01/01/2017"="New Year’s Day"; "01/16/2017"="Martin Luther King Day"; "02/02/2017"="Presidents Day"; "05/29/2017"="Memorial Day"; `
	"07/04/2017"="Independence Day"; "11/4/2017"="Labor Day"; "11/23/2017"="Thanksgiving Break"; "11/24/2017"="Thanksgiving Break"; "12/25/2017"="Christmas Day"}

foreach($holiday in $holidays.GetEnumerator() | Sort Key)
{
	[string]$hName = $holiday.Value
	$hDate = Get-Date $holiday.Key
	
	$appt = $calendar.Items.Add(1) 
	$appt.Start = $holiday.key.ToString()
	$appt.AllDayEvent = $true
	$appt.Subject = $hName
	$appt.Body = $hName

	<#
	Show As / Status
	0 = Free 
	1 = Tentative 
	2 = Busy 
	3 = Out of Office 
	#>
	$appt.BusyStatus = 3

	$appt.Save()
}

This post helped guide me in the right direction:
Create a calendar item

Get all Groups and Users in a Site Collection or Web

Recently a user contacted me asking how to get all the groups and users in a site and subsites.

Both example will output to the C:\ drive of the server.

This script will output all the groups and user from the root of a site collection and all the subsites.
$site = Get-SPSite "http://sharepointed.com"

$userOutput = @()

foreach($subWebs in $site.AllWebs)
{
Write-Host $subWebs.Title

$groups = $subWebs.sitegroups

foreach($group in $groups)
{
$object = New-Object PSobject
$object | Add-Member -Name ‘Web URL’ -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name ‘Web Title’ -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name ‘Group’ -MemberType Noteproperty -Value $group.Name
$userOutput += $object

foreach($userG in $group.users)
{
$object = New-Object PSobject
$object | Add-Member -Name ‘Web URL’ -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name ‘Web Title’ -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name ‘Group’ -MemberType Noteproperty -Value $group.Name
$object | Add-Member -Name ‘Account’ -MemberType Noteproperty -Value $userG.Name

$userOutput += $object
}
}
}

$userOutput | export-csv c:\site_collection_$(get-date -f yyyy-MM-dd-hhmmss).csv -notypeinformation

 

This script will output all the groups and users from a single web.
$web = Get-SPWeb "http://sharepointed.com/sites/taco/SubSite"

$userOutput = @()

$groups = $web.Groups
$users = $web.Users

#get groups and users in the groups
foreach($group in $groups)
{
$object = New-Object PSobject
$object | Add-Member -Name 'Web URL' -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name 'Web Title' -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name 'Group' -MemberType Noteproperty -Value $group.Name
$userOutput += $object

foreach($userG in $group.users)
{
$object = New-Object PSobject
$object | Add-Member -Name 'Web URL' -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name 'Web Title' -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name 'Group' -MemberType Noteproperty -Value $group.Name
$object | Add-Member -Name 'Account' -MemberType Noteproperty -Value $userG.Name

$userOutput += $object
}
}
#get users not in groups
foreach($user in $users)
{
$object = New-Object PSobject
$object | Add-Member -Name 'Web URL' -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name 'Web Title' -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name 'Group' -MemberType Noteproperty -Value ""
$object | Add-Member -Name 'Account' -MemberType Noteproperty -Value $user.Name

$userOutput += $object
}

$userOutput | export-csv c:\web_$(get-date -f yyyy-MM-dd-hhmmss).csv -notypeinformation

Add and Remove Shell Access in SharePoint Using PowerShell

How do you add or remove shell access on a web apps content databases?

This script will grant shell access to a user on all the content databases associated with a content database.

$contentDbs = Get-SPContentDatabase -WebApplication "http://yourSharePointWebApp.com/"

foreach($db in $contentDbs)
{
	Add-SPShellAdmin -UserName "domain\user"  -database $db
}

Remove shell access

$contentDbs = Get-SPContentDatabase -WebApplication "http://yourSharePointWebApp.com/"

foreach($db in $contentDbs)
{
	Remove-SPShellAdmin -UserName "domain\user"  -database $db
}

After running the remove script, make sure you check the WSS_Admin_WPG and WSS_WPG groups on the servers in your farm.

Error Microsoft.Office.RecordsManagement.RecordsRepository.Record

One one my testers was receiving this error when testing a PowerShell script that was doing records management in SharePoint.

System.Management.Automation.RuntimeException: Unable to find type [Microsoft.Office.RecordsManagement.RecordsRepository.Records]: make sure that the assembly containing this type is loaded.
at System.Management.Automation.TypeLiteral.resolveType()
at System.Management.Automation.TypeNode.ResolveType()
at System.Management.Automation.TypeNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.AssignmentStatementNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)

User was remoted into a SharePoint server, but did not have the right permissions on the server. I tried adding the user to Power Users group, but that didn’t help. Ended up adding the users to the local server Administrators group and the error went away.

Error When Using PowerShell to Call SharePoint Web Service

New-WebServiceProxy : The HTML document does not contain Web service discovery information.
At C:\myScript.ps1:91 char:17
+ ...    $Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (http://mySharePoint....bin/Search.asmx:Uri) [New-WebServiceProxy], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.NewWebServiceProxy

First attempt at calling the search.asmx service.

$webServ = "http://mySharePointsite.com/_vti_bin/Search.asmx"
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ
$Results = $Service.Query($QueryPacket.OuterXml)

After adding ?wsdl to the uri string, it worked.

$webServ = "http://mySharePointsite.com/_vti_bin/Search.asmx?wsdl"
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ
$Results = $Service.Query($QueryPacket.OuterXml)

Use UserGroup.asmx to get all the users in a SharePoint site

This is a little tricky. I was looking for a way to list all the users that you see in Site Settings –> People and Groups, but I found more info than I needed. This post will be updated once I can track down the actual site users.

The script uses the Users and Groups web service to pull all the users in the site collection.
UserGroup.asmx

In my case, the LoginName is setup like this: domain\username

First try:

$webServ = "http://sharepointed/sites/MySiteCollection/_vti_bin/UserGroup.asmx"
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ 
$Users = $Service.GetUserCollectionFromSite().Users 
$UserNames = New-Object System.Collections.Generic.List[System.Object]

$Users.User | ForEach-Object {
	$spUser = $_.LoginName.Split('\')[1]
	$UserNames.Add($spUser)
}

Found the answer to my question. Using the Lists.asmx service, I was able to query the UserInfo list for all the site users.

$webServ = "http://sharepointed/sites/MySiteCollection/_vti_bin/Lists.asmx"
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ 

$UserNames = New-Object System.Collections.Generic.List[System.Object]

$listname = 'UserInfo'
$listItems = $Service.GetListItems($listname, $null, $null, $null, $null, $null, $null)

for ($counter = 0;$counter -lt $listItems.data.row.Count;$counter++)
{
	$UserNames += $listItems.data.row[$counter].ows_Name
}

Using c# to get at the information. Here I output the LoginName (domain\userName).

            #create a Web Reference to http://yoursiteURL/_vti_bin/usergroup.asmx?wsdl
            #in my case, i named the reference wsUsersGroups
            wsUsersGroups.UserGroup _WSUsersGroups = new wsUsersGroups.UserGroup();
            _WSUsersGroups.Url = "http://sharepointSite/sites/SiteCollectionName/_vti_bin/usergroup.asmx";
            _WSUsersGroups.Credentials = System.Net.CredentialCache.DefaultCredentials;
            XmlNode ndUsers = _WSUsersGroups.GetAllUserCollectionFromWeb();

            StringReader rdrGroups = new StringReader(ndUsers.OuterXml);
            DataSet dsGroups = new DataSet();
            dsGroups.ReadXml(rdrGroups);

            StringBuilder sb = new StringBuilder();

            foreach (DataRow item in dsGroups.Tables[1].Rows)
            {
                sb.AppendLine(item[3].ToString());
            }

            File.WriteAllText("C:\\Users\\myname\\Desktop\\siteUSers.csv", sb.ToString());

PowerShell to get all users group and objects from Active Directory

Get every object and property:

Get-ADUser -Filter * -Properties *| select * | Export-CSV "C:\PS_Every_Object.csv"

^ Depending on the number of user this could take a few minutes to run. This is also handy to hunt for properties.

This will export userId, email, employee Id, and company name.

Get-ADUser -Filter * -Properties SamAccountName,EmailAddress,EmployeeID,Company | select SamAccountName,EmailAddress,EmployeeID,Company | Export-CSV "C:\Email_Addresses.csv"

SOLVED: Exception calling “StartWorkflow” with “X” argument(s)

Trying to start a SharePoint workflow using PowerShell and I couldn’t get past this error:

Exception calling “StartWorkflow” with “4” argument(s): “Object reference not set to an instance of an object.”

or

Exception calling “StartWorkflow” with “3” argument(s): “Object reference not set to an instance of an object.”

 

NO clue if there is a bug in my farm, but the script below works.  Ended up having to re-get the item when running the workflow. $manager.StartWorkflow($list.GetItemById($item.ID),$assoc,$data,$true)

$web = Get-SPWeb "http://rootSiteCollection.com"
$list = $web.Lists["Shared Documents"]

$assoc = $list.WorkFlowAssociations |Where { $_.Name -eq "tacoWF"}
$data = $assoc.AssociationData
$manager = $web.Site.WorkflowManager

$sQuery = New-Object Microsoft.SharePoint.SPQuery 

#Get all items with an ID greater than 5 
$caml = '<Where><Gt><FieldRef Name="ID" /><Value Type="Counter">5</Value></Gt></Where>'
$sQuery.Query = $caml
$fItems = $list.GetItems($sQuery)

Foreach($item in $fItems)
{
	$manager.StartWorkflow($list.GetItemById($item.ID),$assoc,$data,$true)
}

 

Are SharePoint Designer Workflows Using Custom Features or Solutions (iLoveSharePoint)

Needed to audit a farm to see if a CodePlex solution was being used in SharePoint Designer workflows.  In my case, I needed to see where the iLove SharePoint  solution was being used. The script below is only targeted at one web and is looking for word “ILoveSharePoint” in the XML.

 


if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) 
{
	Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges(
	{

		$resultsarray =@()
		#output file name
		$fileName = "C:\ilsp-" + $(Get-Date -Format "yyyyMMddHHmmss") + ".csv"
		#name of the feature we are looking for
		$wFeatureName = "ILoveSharePoint"

		Function GetFiles($folder)
 { 
			foreach($file in $folder.Files)
			{
				if($file.Name.Split('.')[-1] -eq "xoml")
				{
					$web2 = Get-SPWeb $file.Web.Url
					$wFile = $web2.GetFileOrFolderObject($web2.URL +"/"+ $file.URL)

					if ($wFile.Exists -eq "True")
					{
						$wXml = (New-Object System.Text.UTF8Encoding).GetString($wFile.OpenBinary());
						$nsDetail = $wXml.OuterXml.ToLower()
						
						$wFeatureName = $wFeatureName.ToLower()
							
						if($nsDetail -Like "*$wFeatureName*")
						{
							$outFolder = $folder -replace "Workflows/",""

							$outObject = new-object PSObject
							$outObject | add-member -membertype NoteProperty -name "URL" -Value $web2.Url
							$outObject | add-member -membertype NoteProperty -name "Workflow" -Value $outFolder
							$outObject | add-member -membertype NoteProperty -name "Created By" -Value $wFile.Author
							$outObject | add-member -membertype NoteProperty -name "Created Date" -Value $wFile.TimeCreated
							$outObject | add-member -membertype NoteProperty -name "Modified By" -Value $wFile.ModifiedBy
							$outObject | add-member -membertype NoteProperty -name "Modified Date" -Value $wFile.TimeLastModified

							$global:resultsarray += $outObject
						}
					} 
				} 
			}

			# Use recursion to loop through all subfolders.
			foreach ($subFolder in $folder.SubFolders)
			{
				GetFiles($Subfolder)
			}
		}

		$WebApplications = Get-SPWebApplication

		foreach($webApp in $WebApplications)
		{
			foreach($site in $webApp.Sites)
			{
				if ((Get-SPSite $site.url -ErrorAction SilentlyContinue) -ne $null) 
				{
					foreach($web in $site.AllWebs)
					{
						if ((Get-SPWeb $web.url -ErrorAction SilentlyContinue) -ne $null) 
						{
							$list1 = $web.Lists.TryGetList("Workflows")
							if($list1 -ne $null)
							{
								GetFiles($list1.RootFolder)
							}
						}
					}
				}
			}
		}

		#output file
		$resultsarray | Export-csv $fileName -notypeinformation

	}
)