4

I have next powershell code for getting page url by item

function Get-ItemUrl($item){
    $urlOptions = [Sitecore.Links.LinkManager]::GetDefaultUrlOptions()
    $urlOptions.AlwaysIncludeServerUrl = $True
    $urlOptions.ShortenUrls = $True
    $urlOptions.SiteResolving = $True;
    $url = [Sitecore.Links.LinkManager]::GetItemUrl($item, $urlOptions)
    $url
}

in general code works good, but on production it is return page URL via HTTP protocol instead of HTTPS. Why it is happens how to solve it ?

  • Do you have scheme="https" on your site definition? Please edit your post to include the site definition from /sitecore/admin/ShowConfig.aspx. – Dmytro Shevchenko Jun 27 '17 at 12:38
  • @DmytroShevchenko setting is correct if you speak about hostName,targetHostName , and schema – Arbejdsglæde Jun 27 '17 at 12:59
  • That's the issue. The attribute needs to be named scheme, not schema. This is a common mistake, because the two words are so similar. – Dmytro Shevchenko Jun 27 '17 at 13:06
  • @DmytroShevchenko I did it only here ))) – Arbejdsglæde Jun 27 '17 at 13:39
  • 2
    If it is the issue @jammykam said, here's an SE answer that shows how to use the SiteContextSwitcher from SPE that would change the site context to the one you wanted, instead of the shell: sitecore.stackexchange.com/questions/3897/… – Matthew FitzGerald-Chamberlain Jun 27 '17 at 20:00
7

Your problem is that Powershell is running in the context of the "shell" site, which gives you /sitecore/shell as the path. When using Sitecore.Links.LinkManager.GetItemUrl(), you'll need to be in the context of the site for which you want the URL. For this, you can use the SiteContextSwitcher, which can be used in a using block. In C#, you would do this as follows:

var site = Sitecore.Sites.SiteContext.GetSite("website");

using (var siteContextSwitcher = new SiteContextSwitcher(site)) {
    var urlOptions = Sitecore.Links.LinkManager.GetDefaultUrlOptions();
    urlOptions.AlwaysIncludeServerUrls = true;
    urlOptions.ShortenUrls = true;
    urlOptions.SiteResolving = true;
    var url = Sitecore.Links.LinkManager.GetItemUrl(item, urlOptions);
}

In Powershell, you'll need to use the New-UsingBlock cmdlet:

function Get-ItemUrl($item){
    $site = [Sitecore.Sites.SiteContext]::GetSite("website")

    New-UsingBlock(New-Object -TypeName "Sitecore.Sites.SiteContextSwitcher" -ArgumentList $site) {
        $urlOptions = [Sitecore.Links.LinkManager]::GetDefaultUrlOptions()
        $urlOptions.AlwaysIncludeServerUrl = $True
        $urlOptions.ShortenUrls = $True
        $urlOptions.SiteResolving = $True;
        $url = [Sitecore.Links.LinkManager]::GetItemUrl($item, $urlOptions)
        return $url
    }
}

However, if you're running this on a CM instance, the URL that you get now will use the hostname and scheme of the the site on the CM instance. Assuming you're looking for the URL for CD, you'll need to do some parsing, as the CM instance doesn't know the hostname and scheme for the CD instance.

function Get-ItemUrl($item){
    $site = [Sitecore.Sites.SiteContext]::GetSite("website")

    New-UsingBlock(New-Object -TypeName "Sitecore.Sites.SiteContextSwitcher" -ArgumentList $site) {
        $urlOptions = [Sitecore.Links.LinkManager]::GetDefaultUrlOptions()
        $urlOptions.AlwaysIncludeServerUrl = $True
        $urlOptions.ShortenUrls = $True
        $urlOptions.SiteResolving = $True;
        $urlString = [Sitecore.Links.LinkManager]::GetItemUrl($item, $urlOptions)
        $url = New-Object -TypeName System.Uri -ArgumentList $urlString
        $absolutePath = $url.AbsolutePath
        return "https://mysite.com" + $absolutePath
    }
}

Notice that we still use AlwaysIncludeServerUrl so that the URI we generate will be able to be parsed by the System.Uri constructor. We then strip out the CM hostname and scheme, and replace it with the scheme and hostname for the CD instance (in this case, https://mysite.com)

Note: There's no error handling currently. For example, if you don't have the scheme or hostname set on the site node, it won't generate a URL that can be parsed by the System.Uri constructor. In this case, make sure that your site node is fully configured, or modify the code to make sure that the URL is valid and fully-qualified before you pass it to the System.Uri constructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.