What if there were no ad blockers?

Sometimes I browse the web without an ad blocker. It’s typically a horrible experience. I don’t understand how people stand it.

I don’t watch TV any more, and a big part of this is that I can’t stand the ads. But TV ads are predictable and can be avoided by changing the channel or muting the sound and go out to the kitchen to grab a beer. Web ads are much more in your face.

I wonder what my life would be if there were no ad blockers. I admit that I spend a good amount of time procrastination at different sites. But if I had been forced to watch their ads, I’m not sure I would any more.

Perhaps, in a world without ad blockers, I would be a more productive person due to the lack of distractions. And being productive is a great feeling. Perhaps a world without ad blockers would not be that bad after all…

Posted in Opinion & Thoughts | Tagged , , , | 3 Comments

Maximizing Hyper-V Windows (instead of full screen)

I recently started using Hyper-V after being used to VMware. I want my virtual machine windows maximized, but not full screen since I need to quickly move between the host and virtual machines. In VMware the maximize button will do what it is intended for – maximizing the window – but Hyper-V will instead enter fullscreen mode when you maximize the window. Very annoying. It took me quite a while until I found a way around this:

Use the mouse to drag the window to the top of the screen. It will “snap” into place maximizing the window!

Note: This works only in “enhanced sessions”

Posted in Tips | Tagged , , , , | 2 Comments

Transparent CSS borders with the inherited color

You can inherit CSS colors from parent elements using the  inherit  or  currentColor  keywords:

This works for border color too:

But suppose you’d want to have a semi-transparent color. When setting colors normally you would simply use  rgba()  to specify the transparency:

But this does not work for inherit or currentColor since rgba does not accept these keywords. But with a little trickery we can use the  :before  pseudoelement to get the same effect:

Cool :-)

Posted in Development, Tips | Tagged , | 1 Comment

MS Teams fullscreen view?

Microsoft Teams does not have a “true” fullscreen mode. Even if you select both “focus” and “fullscreen” there is always a command bar left at the top. This can make it difficult read small text when people are sharing their (high resolution) screens. Here are two tips how to improve:

1. Pressing Ctrl+Minus will make the Teams GUI smaller. Do this multiple time. Each time the shared video gets more room! (You can always press Ctrl+Equals to go back to 100% zoom.)

2. While hovering the shared content, hold Ctrl and use the mouse wheel to zoom in and out. Only the shared screen is affected. When zoomed in, use the mouse to drag the content around.

3. Use the web version of Teams instead. This actually has a *real* fullscreen mode. (It’s not a problem to have both the web version and the ordinary desktop client running at the same time!)

As a side note: From time to time I’ve had problems with viewing screen shares in Teams. The framerate of the incoming video is extremely bad and drops to something like one frame per *minute*. In these cases I have had better result using the web version instead of the ordinary client. Still not super fluid, but at least good enough so you can follow the conversion.

Posted in Tips | Tagged , | 2 Comments

Hacking DocX files to fix Quick Parts in Word Online

Microsoft Word documents can have Quick Parts connected to SharePoint fields, so that the value of the field is displayed inside the document. But Word Online (still) does not fully support this. It will display Quick Parts with a a placeholder text instead of the actual value. If the SharePoint list value changes, the document must be opened in the desktop client for the placeholder text to update and show correctly in Word Online.

This caused trouble for me when I was migrating thousands of files into SharePoint Online. I had a script that uploaded documents and tagged them with important metadata. This metadata was supposed to be displayed in the document, but in Word Online the field name was shown instead (as a placeholder). This was not acceptable, especially since Word Online is default when opening a Word document in SharePoint. I tried to use the Word Automation COM API to make a script that updates these values, but it does not allow editing these fields. What to do?

Here I present a solution to update the placeholder values from PowerShell. It works by unzipping the DocX files to directly modify the XML files. Hacky, but it works :-)

This is not a generic script. It was written for my own needs. Modify and adapt the script to suit your needs before running. For example, it does not show how to get the field values to replace the placeholders with. In my case I had a separate CSV file with migration data. Below I just use a simple key/value structure to map placeholders (e.g. [Author]) to a value. A colleague told me he actually found the “real” values elsewhere in the DocX file. I have not verified this, but perhaps it is possible to read these values instead.

Note: Due to a bug in Compress-Archive make sure to first update it or else Word Online will think the documents are corrupt and only open them in view mode: Install-Module Microsoft.PowerShell.Archive -MinimumVersion -Repository PSGallery -Force -AllowClobber

Update: Forgot to use HtmlEncode() to avoid corrupting the XML

Posted in Development, Tips | Tagged , , , , , , | Leave a comment

Migrating data from Access to SQL Server

Suppose that you have a simple Microsoft Access database that you need to migrate to another database such as MS SQL Server. You model the tables and relationships in the new database, and now you need to export the actual data from Access and import it into the new database. This is how I did it:

I began by exporting the data as CSV. I found the easiest way was to simply use copy/paste. First though, open each tables in Design View. There is a tab named “Lookup” at the bottom. Ensure that any lookup field is set to display “Value List” instead of “Table/Query”. Then you can view the table normally and copy all data to the clipboard (Ctrl+A, Ctrl+C) and paste it into a .csv text file saved with UTF-8 encoding.

Next I used PowerShell to transform the CSV data into to SQL statement. While doing this I also adapted the structure of the data. For example, some fields were renamed, and I also had multiple fields that I wanted to merge into one. Here is a generic version of the script I put together that you can modify to your own needs:

Note: Normally you let SQL Server generate the ID of key fields. In this case though, we already have ID:s from the Access database. Since these ID:s specify the primary-foreign key relations, it is important to keep intact. To allow insertion of keys like that, IDs SET IDENTITY_INSERT Chemicals ON  is used.

Finally, open the generated SQL script (provisioning.sql) in SQL Server Management Studio (or similar) and run it to provision your data!

Posted in Development, Tutorials | Tagged , , , , , , | 1 Comment

Applying SharePoint Retention Labels Programmatically

So you’ve created and published Retention Labels in Office 365 and now you want to apply labels by CSOM code. It’s not very well documented. The following (crude) code should help you get started applying labels to both individual items and to set as default for the whole library:

First some boilerplate initialization…

Get all labels available on the site:

Get the default label for a list:

Get labels for all items in a list:

Write label to a list item:

Set the default label for a list:

SetComplianceTag and SetListComplianceTag have parameters (isTagPolicyHold, isTagPolicyRecord and isEventBasedTag) that are not documented what they actually do. Above I have set them to false. If you know what they do, please leave a comment!

Posted in Development | Tagged , , , , , , , , , | 4 Comments

If Snipping Tool freezes and blocks your screen…

Note: Be sure to read the comments for more help!

Today when I used the Snipping Tool in Windows 10 it stopped working. I could select an area over and over again, but it never closed after that as it should. The screen was dimmed and I could not get to any other program because Snipping Tool was on top of everything, even Task Manager! I almost gave up doing a hard reset, when I found a way to get rid of it:

Alt+Tab still worked though. There is a small X that appears if you hover an application thumbnail with the mouse. Using this you can close Snipping Tool!


Posted in Tips | Tagged , , | 88 Comments

How to create searchable user profile properties in SharePoint Online

In this post I will go through the steps of creating a custom user profile attribute that is searchable and shows on the user profile in Delve. It’s not very hard but involves quite a few steps to keep track of. This is written for SharePoint Online, but the basics apply to SharePoint 2013/2016/2019 as well.

Add a new User Profile Property

Go to SharePoint Admin > User Profiles > Manage Users Properties then click on New Property. Configure the basic settings such as names and type. (Remember that you can’t changes the type after it has been created)

To make the property show up on Delve profiles, ensure the following settings:

  • Default Privacy Setting: Everyone
  • Show in the Profile Properties section of the user’s profile page: Checked
  • Show on the Edit Details page: Checked
  • Indexed: Checked

Ensure the field is crawled

Now we need to wait until the property has been crawled by search. This will not happen unless we fill out the field on at least one user profiles. So start by editing a profile or two.

Then go to SharePoint Admin > Search > Manage Search Schema > Crawled Properties  and wait until your new property shows up. Have patience as this may take a little while (anything from 15 minutes to four hours in my experience).

Map to a managed property

Go to SharePoint Admin > Search > Manage Search Schema > Manage Properties. Create a new Managed Properties with the following settings:

  • Type: Text
  • Searchable: Checked
  • Queryable: Checked
  • Retrievable: Checked
  • Click Advanced Searchable Settings and select PeopleIdx in the popup window
  • Click the blue button “Add a Mapping” and find the crawled property we just created

Finish up

Now we wait again to let search crawl pick up the new managed property. This may take quite a while, and you never know when it happens in SharePoint Online. I typically leave it during the night and check in the morning…

If you have done everything correct, you will now have a custom user property that you can freely search for all over Office 365 to find people, and that you can view on peoples Delve profiles!

Notes & tips

  • If you have business requirements to only allow a limited set of values to enter into the property, you can create a term set in the Term Store with allowed values. Then, when creating the new property, select string as type and tick the “Configure a Term Set to be user for this value” checkbox.
  • The properties you create are visible in Delve under “Additional Information” at the bottom of user’s profile pages. If you allow users to edit the properties themselves, they can do so on the SharePoint Profile page. To find it, go to https://tenant-my.sharepoint.com/_layouts/15/editprofile.aspx
  • Managed properties that you create yourself in SharePoint Online can not be sorted or refined in search results. If you need to do this, you can add another managed property, but instead of creating it yourself use one of the predefined RefinableString properties.
  • To easily update properties in multiple user profiles, check out the Bulk User Profile Update Api for SharePoint Online.
  • There is no way in SharePoint Online to control when search will crawl user properties. This script may help ensuring that your user profiles are re-indexed: https://github.com/wobba/SPO-Trigger-Reindex
Posted in Tutorials | Tagged , , , , , , , , | 1 Comment

Popup opens as new browser window in Edge and Internet Explorer

Problem: Opening a popup with JavaScript in Edge or Internet Explorer results in a new browser window instead of a popup window. For example:

Communication between the new window and originating site is not possible either, since both popup (above) and window.opener (in the new window) are undefined.

Solution: This can happen if the originating site’s URL and popup URL are not in the same security zone. Ensure that both are in the Trusted Sites zone in Internet Options!

Posted in Development | Tagged , , , , , | Leave a comment