Hyper-V Client Window is Black

New Dell XPS 15
Enabled Hyper-V and tried to create a Server 2012 VM.
Client window was black but the preview window was displaying the correct view of the client OS.
The other fixes that appear on Google did not apply because I was in the process of setting up a new VM.

Fix:
With Hyper-V running and the client window open.
Open the NVIDIA control panel
Click on Manage 3D settings
1. select a program to customize
Select c:\windows\system32\vmconnect.exe
IF you are not able to select this, click the Add button and locate it in the displayed list of programs.
2. Select the preferred…..
Select Integrated graphics
Click Apply

Now, close the Hyper-V client window and reopen it.

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!

CLOSE Outlook before running the script.

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()
}

You might see this error if you haven’t CLOSED Outlook:

new-object : Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to
the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
At C:\Code\PS\SPO_BHP\Set_Holidays.ps1:19 char:12
+ $outlook = new-object -com Outlook.Application
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
+ FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand

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

The Web server at does not appear to have Microsoft SharePoint Foundation installed

When you try to open a SharePoint site from SharePoint Designer and you receive this error:
The Web server at does not appear to have Microsoft SharePoint Foundation installed

sharepoint-not-installed

Microsoft suggests doing the follow (did not work in my case)

To resolve this problem, enable the client integration. To do this, follow these steps:
Start SharePoint 2010 Central Administration, and then click Security.
Click Specify authentication providers.
If the Web application in the Web Application list is not the same application that you want to open in SharePoint Designer 2010, click Web Application on the Change Web Application list.
On the Select Web Application page, click the name of the Web application that you want to open.
Under Zone, Click Default to open the Edit Authentication page.
Under Enable Client Integration, click Yes, and then click Save.

In my case, it turned out that my web.config file was out of wack.
Only one of my web apps would fail to load in SharePoint Designer, all the other Web Apps / sites would load.
Opened a working and the non-working sites web.configs in NotePad++ and did a file compare.
Located the difference in the file and removed it.
For good housekeeping, i then fired off an IISreset.
*things to note, make sure you have a backup copy of your web.config file and this work was done in my Develop environment.)

Download all files from a document library using client object model

For this to work, you will need to obtain a copy of the SharePoint Client DLL (microsoft.sharepoint.client.dll).

On a server with SharePoint intalled:
SharePoint 2010: 14 hive
SharePoint 2013: 15 hive
SharePoint 2016: 16 hive
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\

In Visual Studio, create a console application and name it Download_All_Files. Copy all the code below and paste it into your code window. Update site URLs and list name (Taco Storage).

Using this process, I was able to download 10,000 documents from a library. Took around 30 minutes to complete.

using System;
using System.IO;
using Microsoft.SharePoint.Client;

namespace Download_All_Files
{
    class Program
    {
        static void Main(string[] args)
        {
            // input YOUR URL below
            var site = new ClientContext("http://sharepoint/sites/somesite");
            var web = site.Web;
            site.Load(web);
            site.ExecuteQuery();
            // CHANGE THIS to your library name, get this from the Library Settings page
            List list = web.Lists.GetByTitle("Taco Storage");
            site.Load(list);
            site.ExecuteQuery();
            site.Load(list.RootFolder);
            site.ExecuteQuery();
            site.Load(list.RootFolder.Folders);
            site.ExecuteQuery();
            processFolderClientobj(list.RootFolder.ServerRelativeUrl);
            foreach (Folder folder in list.RootFolder.Folders)
            {
                processFolderClientobj(folder.ServerRelativeUrl);
            }
        }
        public static void processFolderClientobj(string folderURL)
        {
            // folder on your computer where all the files will be downloaded to
            string Destination = @"C:\\yourFolder";
            
            // input YOUR URL below
            var site = new ClientContext("http://sharepoint/sites/somesite");
            var web = site.Web;
            site.Load(web);
            site.ExecuteQuery();
            Folder folder = web.GetFolderByServerRelativeUrl(folderURL);
            site.Load(folder);
            site.ExecuteQuery();
            site.Load(folder.Files);
            site.ExecuteQuery();
            foreach (Microsoft.SharePoint.Client.File file in folder.Files)
            {
                string destinationfolder = Destination + "/" + folder.ServerRelativeUrl;
                Stream fs = Microsoft.SharePoint.Client.File.OpenBinaryDirect(site, file.ServerRelativeUrl).Stream;
                byte[] binary = ReadFully(fs);
                if (!Directory.Exists(destinationfolder))
                {
                    Directory.CreateDirectory(destinationfolder);
                }
                FileStream stream = new FileStream(destinationfolder + "/" + file.Name, FileMode.Create);
                BinaryWriter writer = new BinaryWriter(stream);
                writer.Write(binary);
                writer.Close();
            }
        }
        public static byte[] ReadFully(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
    }
}

Add and Remove Shell Access in SharePoint Using PowerShell

How do you add or remove shell access to 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.

Specify a Search Scope When Using search.asmx Service

This article will outline how to setup your code:  link

For my app, I needed to leverage a search scope as part of my query.  Note: when setting up the XML packet, pay close attention to your spacing and closing tags.  If not, you will run into endless error’s that have little to no relevant description.

Example:

<ResponsePacket xmlns="urn:Microsoft.Search.Response"><Response domain="QDomain"><Status>ERROR_BAD_REQUEST</Status><DebugErrorMessage>Name cannot begin with the ' ' character, hexadecimal value 0x20. Line 1, position 442.</DebugErrorMessage></Response></ResponsePacket>

Here is my code example. Keep in mind that I’ve already setup my web reference (_vti_bin/Search.asmx).

                var webServ = "http://rootSiteUrl/mysitecolleciton/_vti_bin/Search.asmx";

                QueryService qService = new QueryService();
                qService.Credentials = System.Net.CredentialCache.DefaultCredentials;
                qService.Url = webServ;

                SearchQuery sQuery = new SearchQuery();
                var querySetup = sQuery.SearchString("my search value");
                var queryResults = qService.QueryEx(querySetup);

    class SearchQuery
    {
        public string SearchString (string entityId )
        {
            StringBuilder queryXml = new StringBuilder();
            queryXml.Append("<QueryPacket xmlns=\"urn:Microsoft.Search.Query\" Revision=\"1000\">");
            queryXml.Append("<Query domain=\"QDomain\">");
            queryXml.Append("<SupportedFormats><Format>urn:Microsoft.Search.Response.Document.Document</Format>");
            queryXml.Append("</SupportedFormats>");
            queryXml.Append("<Context>");
            queryXml.Append("<QueryText language='en-US' type='MSSQLFT'>");
            queryXml.Append("SELECT Title, Path, Description, Write, Rank, Size FROM Scope() WHERE \"Scope\" = 'Big - Scope' AND CONTAINS(owsOrderx0020Number,'" + entityId +"')");
            queryXml.Append("</QueryText>");
            queryXml.Append("</Context>");
            queryXml.Append("</Query>");
            queryXml.Append("</QueryPacket>");

            return queryXml.ToString();
        }
    }

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
[xml]$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
[xml]$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());