fredag den 27. maj 2011

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

So when playing with SharePoint 2010 using claims based authentication of cource sometimes I would see the above error. It really didn’t make much sense. I was doing everything as administrator and I could do the same thing from the administration website, but not powershell.

for instance

$snapin = Get-PSSnapin | where {$_.name -eq 'Microsoft.SharePoint.PowerShell'}
if($snapin -eq $null){ Add-PSSnapin Microsoft.SharePoint.PowerShell }
$webappurl = 'someweb.domain.com'
$spsite = get-spsite "https://$webappurl"
$spweb = get-SPWeb -site $spsite
Get-SPWeb : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:19
+ $spweb = get-SPWeb <<<<  -site $spsite
    + CategoryInfo          : InvalidData: (Microsoft.Share....SPCmdletGetWeb:SPCmdletGetWeb) [Get-SPWeb], Unauthorize   dAccessException
    + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletGetWeb

Well, not sure if this is a “prober” solution, but this worked for me.
Open Central Administration –> Security –> Configure managed accounts
Make sure the user that gets above error is registered.

Open Central Administration –> Security –> Configure service accounts
Select Farm Account –> Select the account from the dropdown menu and click OK

Scripting ADFS 2.0 to make Sharepont 2010 relying party trust

I really wanted to use Set-ADFSRelyingPartyTrust –IssuanceTransformRules but for some weird reason no matter how I setup the paramteres I would just “screw” up the Claim Rules when watching the GUI so ended up using a ClaimRuleFile instead.

$snapin = Get-PSSnapin | where {$_.name -eq 'Microsoft.Adfs.PowerShell'}
if($snapin -eq $null){ Add-PSSnapin Microsoft.Adfs.PowerShell }

$Identifier = @(("https://" + $webappurl +"/_trust/"),('urn:sharepoint:' + $webappurl))
$rpt = Get-ADFSRelyingPartyTrust $webappurl
if(!$rpt) { $rpt = Add-ADFSRelyingPartyTrust -Identifier $Identifier -name $webappurl -EncryptionCertificateRevocationCheck None }
# Set-ADFSRelyingPartyTrust -TargetName $webappurl -EncryptionCertificateRevocationCheck None
Set-ADFSRelyingPartyTrust -TargetName $webappurl -Identifier $Identifier

$IssuanceAuthorizationRules = '@RuleTemplate = "AllowAllAuthzRule" => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");'
Set
-ADFSRelyingPartyTrust -TargetName $webappurl -IssuanceAuthorizationRules $IssuanceAuthorizationRules

$rSet = New-ADFSClaimRuleSet -ClaimRuleFile 'X:\SPS_2010_prov\IssuanceTransformRules.txt'
Set
-ADFSRelyingPartyTrust -TargetName $webappurl -IssuanceTransformRules $rSet.ClaimRulesString
# $IssuanceTransformRules = '@RuleTemplate = "LdapClaims" @RuleName = "Pass-through LDAP Claims" c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"), query = ";sAMAccountName,mail,tokenGroups;{0}", param = c.Value);'
#
Set-ADFSRelyingPartyTrust -TargetName $webappurl -IssuanceTransformRules $IssuanceTransformRules

#$samlEndpoint = New-ADFSSamlEndpoint -Protocol 'SAMLAssertionConsumer' -Uri ('https://' + $webappurl + '/_trust/') -Binding 'POST' -IsDefault $true -Index 0
#
Set-ADFSRelyingPartyTrust -TargetName $webappurl -SamlEndpoint $samlEndpoint

Set
-ADFSRelyingPartyTrust -TargetName $webappurl -WSFedEndpoint "https://$webappurl/_trust/"

#Set-ADFSRelyingPartyTrust -TargetName $webappurl -TokenLifetime 5


And heres the content on IssuanceTransformRules.txt (note its just a plain copy’n’paste from (Get-ADFSRelyingPartyTrust $webappurl).IssuanceTransformRules )


@RuleTemplate = "LdapClaims"
@RuleName = "Send LDAP Claims"
c:[Type
== "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"), query = ";sAMAccountName,userPrincipalName,tokenGroups;{0}", param = c.Value);

tirsdag den 17. maj 2011

Remote Desktop RDWeb remoteapp icons reverting to RDP default icon

I’ve had that problem a few times, but I finally found a work around that works every time.

go to C:\Windows\Web\RDWeb\Pages\rdp on the Remote Desktop Web servers and make sure the TS Web Access Computers have access to this folder. Delete all the content and refresh the webpage.

lørdag den 14. maj 2011

Anyone that can explain this ?

It happened again. I have a web project, and added a service reference to a WCF service. I have a few settings I needed loaded on every page, so decided to create a new class and inherit from the WCF Client

image

it compiles fin, but the IDE keeps showing a ton of errors on all the pages that uses this new class. One of the more fun is the below one

image

Bah, if it works why the hell is the IDE showing tons of errors and weird errors. If anyone out there have an idea/workaround that would be nice.

lørdag den 7. maj 2011

ADFS 2.0 and ASP.NET

I want to learn more about ADFS, and possibly use it my self in a few projects, so I set my self the goal to create a simple webpage that implemented SSO through Windows Identity Foundation and using my existing ADFS 2.0 server. I wanted a website that supports anonymous users, and sign on using both Kerberos and Forms based authentication.

Man has that been more reading than testing, but I think I’m starting to get the basic concepts. One of the first things that had me confused was that I had just seen in CRM 2011 to control how ADFS decides to authenticate you was based on URL’s and or FQDN’s. Well, it doesn’t. Yes you can modify FormsSignIn.aspx and IdpInitiatedSignOn.aspx. You can also force a specific way by editing the list of handlers in web.Config on the ADFS server. But that would just break my CRM2011 installation and just felt wrong.

Turns out, ADFS doesn’t decide, YOU decided by setting the authenticationType in the URL used to redirect the user to the ADFS server. Gah, I’m getting away from the point of this blog post. I wanted to give my self and others a quick how to, on how to quickly implement a webpage that supports all the above.

1) install ADFS.

2) on your developer machine, install Windows Identity Foundation SDK. I’m working in .NET 4.0 so just download that and install it. After installation, if you are a VB coder like me you will get disappointed to see you cant find the “Claims based aware website” template. Ah well, screw them we don’t need help, do we ? Open-mouthed smile …Create a new empty website. To save your self *A LOT* of trouble, make it use SSL.

image

image

If you decide to add it later, or just make sure the application in the IIS has force SSL enabled. You can remove it again in a minute don’t worry.

image

Now, right click your website in visual studio and choose “Add STS reference…”

image

Application URI is what people will type in there browser to access your website. Now, you can either run this guide multiple times for each FQDN, or just edit it later in web.config and “Update federation metadata”. Just to be safe I ran the guide twice. Once for the internal URL and once for the external URL. ( the screenshots here is from an test app I call SSI2 )

image

Press next and choose “Use existing STS”, type the URL to your STS ( ADFS 2.0 server. this could ofc also just be the build in STS server in windows 2008 R2 –> Server manager –> Roles –> Add Roles –> “Active Directory Federation Service” … )
In my case the STS is at https://adfs.wingu.dk/FederationMetadata/2007-06/federationmetadata.xml

image

If you don’t have an STS, you can also choose “Create a new STS project” but …
First of all. It is C# and who wants to look at ugly code with an semicolon in the end of every sentence ? and secondly.
You will miss out on all the wonderful trouble shooting and the “WAOUW” feeling when it finally works. With the STS sample you just type a name in the login screen and everything works. Where is the fun in that ?

Next decided if you want the wsFederation to validate certificates. of course you do. *cough*

image

Next choose a certificate used to encrypt tokens send back and forth from the STS and your Web app. You can skip this, but I really don’t recommend it.

image

Accept the confirmation page that also list all the claims you can get from the STS. Don’t worry they will all be in your web.config ready to be “un remarked” for your pleasure.

image

First thing you want to do is update your STS with the new project you just created. Notice the guided added an XML file, you can use to link your STS to your webapp with.

image

Go on, jump to your ADFS and add the URL. Open AD FS 2.0 console and add your Relying Party Trust

image

Choose Import data about the relying party published online or on local network and past in the URL to your application. ( in my case it’s https://admin.wingu.dk/ssi2/FederationMetadata/2007-06/FederationMetadata.xml )

image

Choose default setting the rest of the guide and jump back to Visual Studio.
Open your web.config and go to
configuration->system.web->authorization and remark out the deny rule

<authorization>
  <!-- <deny users="?"/> -->
</authorization>

Hell, while you are there disable errors too, you will see one soon. I promise.

<system.web>
  <customErrors mode="Off"/>
  <authorization>
    <!-- <deny users="?"/> -->
  </authorization>

If you go down to configuration –> microsoft.identityModel –> service-> applicationService –> audienceUris you will see the URL’s you added above.

<audienceUris>
  <add value="https://admin.wingu.dk/ssi2/"/>
  <add value="https://prov01.int.wingu.dk/ssi2/"/>
</audienceUris>

You can edit this at anytime and update it by right clicking your project and choose “Update federation metadata”.
image

Remember you need to refresh this on the ADFS server too

image

Add 2 Web Forms. Default.aspx and login.aspx. On default.aspx drag in a FederatedPassiveSignInStatus and then double click it. Add the following code

Protected Sub FederatedPassiveSignInStatus1_SigningOut(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles FederatedPassiveSignInStatus1.SigningOut
    Dim authModule As WSFederationAuthenticationModule = FederatedAuthentication.WSFederationAuthenticationModule
    Dim signoutUrl As String = WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(authModule.Issuer, authModule.Realm, Nothing)
    WSFederationAuthenticationModule.FederatedSignOut(New Uri(authModule.Issuer), New Uri(authModule.Realm + "Default.aspx"))
End Sub

This code will trigger when the user is logged in, and clicks the “logout” link. If user isn't logged in, and he clicks the “sign in” link, the user gets redirect to login.aspx.

So go to that and add the following code to handle logins.

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    Dim authModule As WSFederationAuthenticationModule = FederatedAuthentication.WSFederationAuthenticationModule
    authModule.PassiveRedirectEnabled = True
    'Dim mess As WSFederationAuthenticationModule.SignInRequestMessage = authModule.CreateSignInRequest("passive", returnUrl, False)
    Select Case Request.Url.Host.ToLower
        'Case "localhost", "prov01", "prov01.int.wingu.dk"
        '    Dim returnUrl As String = "https://prov01.int.wingu.dk/ssi2/"
        '    Dim mess As WSFederation.SignInRequestMessage = authModule.CreateSignInRequest("passive", returnUrl, False)
        '    mess.Realm = "https://prov01.int.wingu.dk/ssi2/"
        '    Dim redirURL As String = mess.WriteQueryString()
        '    Response.Redirect(redirURL)
        Case "localhost", "prov01", "prov01.int.wingu.dk"
            Dim returnUrl As String = "https://admin.wingu.dk/ssi2/"
            Dim mess As WSFederation.SignInRequestMessage = authModule.CreateSignInRequest("passive", returnUrl, False)
            mess.AuthenticationType = "urn:federation:authentication:windows"
            mess.Realm = "https://admin.wingu.dk/ssi2/"
            Dim redirURL As String = mess.WriteQueryString()
            Response.Redirect(redirURL)
        Case Else
            Dim returnUrl As String = "https://admin.wingu.dk/ssi2/"
            Dim mess As WSFederation.SignInRequestMessage = authModule.CreateSignInRequest("passive", returnUrl, False)
            mess.AuthenticationType = "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
            mess.Realm = "https://admin.wingu.dk/ssi2/"
            Dim redirURL As String = mess.WriteQueryString()
            Response.Redirect(redirURL)
    End Select

    'HttpContext.Response.Redirect(mess.WriteQueryString())

End Sub

Yeah, I suck. I haven't solved all the problems yet,I will update this post once I get it working the way I want. But I’m still sure others searching on ADFS might find a bit of this useful. Basically I want to update “AuthenticationType” so that users internally don’t get prompted at all, and just fly’s in via Kerberos and people externally gets ADFS’s forms based login page. Since ADFS has both the internal URL and external URL I would expect the code I remarked out to work, but I keep getting

ID3206: A SignInResponse message may only redirect within the current web application: 'https://prov01.int.wingu.dk/ssi2/' is not allowed.

so instead I force all users to be redirected to the external page. It works, sure but if the user logs out he cant login again using Kerberos ( he's now coming from the external domain ) so he either have to update the URL in the browser or login using forms based authentication. If I find out why I get that error ill update the post. For now this almost solved the goals I set for my self

A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo...").

as follow up to last post. Once you drop your first class into App_Code you will encounter an error stating you cant have both VB and C# code in same directory. Fine, I never did like semicolon anyway, so I deleted WIFSampleRequestValidator.cs and removed

<httpRuntime requestValidationType="SampleRequestValidator"/>

from the system.web part of web.config. First time I try logging in I instantly get

A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo...").

oh, so TTHAAATTSS what the ugly C# code did. Ah well, I added the above statement in web.config and added a new SampleRequestValidator class.

Imports System.Web.Util
Imports Microsoft.IdentityModel.Protocols.WSFederation

Public Class SampleRequestValidator
    Inherits RequestValidator

    Public Sub New()
    End Sub

    Protected Overloads Overrides Function IsValidRequestString(ByVal context As HttpContext, ByVal value As String, _
            ByVal ValidationSource As RequestValidationSource, _
            ByVal collectionKey As String, _
            ByRef validationFailureIndex As Integer) As Boolean
        Try
            validationFailureIndex = -1 ' Set a default value for the out parameter.

            ' This application does not use RawUrl directly so you can ignore the check.
            If ValidationSource = RequestValidationSource.RawUrl Then
                Return True
            End If

            If (ValidationSource = RequestValidationSource.Form) AndAlso _
                collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal) Then

                Dim message As SignInResponseMessage = WSFederationMessage.CreateFromFormPost(context.Request)
                If message IsNot Nothing Then Return True
                Return MyBase.IsValidRequestString(context, value, ValidationSource, collectionKey, validationFailureIndex)
            Else
                ' All other HTTP input checks are left to the base ASP.NET implementation.
                Return MyBase.IsValidRequestString(context, value, ValidationSource, collectionKey, validationFailureIndex)
            End If
        Catch ex As Exception
            Return MyBase.IsValidRequestString(context, value, ValidationSource, collectionKey, validationFailureIndex)
        End Try
    End Function
End Class
Jesus, Microsoft really abandoned their visual basic fans in favor of the semicolon loving people, eh ?

tirsdag den 3. maj 2011

Disable and Enable systemuser in CRM2011

I’ve spend way to many hours goggling this. Hopefully someone in need this will find this post before wasting 9 hours on figuring out how to do something this simple, like I had too.

Function DisableUser(user As SystemUser) As SystemUser
    SetEntityState(user, 1, -1)
    Return getEntity(user.LogicalName, "domainname", ConditionOperator.Equal, user.DomainName)
End Function

Function EnableUser(user As SystemUser) As SystemUser
    SetEntityState(user, 0, -1)
    Return getEntity(user.LogicalName, "domainname", ConditionOperator.Equal, user.DomainName)
End Function

Sub SetEntityState(entity As Entity, state As Integer, Status As Integer)
    Dim request As New SetStateRequest
    request.EntityMoniker = New EntityReference()
    request.EntityMoniker.Id = entity.Id
    request.EntityMoniker.LogicalName = entity.LogicalName
    request.State = New OptionSetValue(state)
    request.Status = New OptionSetValue(Status)
    Dim response As SetStateResponse = cliOrganization.Execute(request)
End Sub

What I did to get to this, was fire up SQL Profiler and look at the SQL being called while disabling and enabling a system user. After messing around inside sdkmessage and sdkmessageproccessingsteps I finally got a few hints and while goggling I stumbles over this page, and gave it a try. And it seemed to work.

ADFS / CRM2011 making my head hurt.

so here is a few things I learn after a week of playing with CRM 2011 with IFD configures.

First thing I did was watch this you tube clip, and do the same except use some other domain names. What I had to watch several times and still not quite understand was when he was using external domain names and internal domain names. That was lesson number 1 learn.

There IS no internal domains. CRM 2011 does not support having more than 1 HTTP and 1 HTTPS binding and since you need a unique IP address per certificate you are kind of forced to use external domain names for everything. So just to make I get this right, I’m going to post the real domain names I am using in this setup.

First off, I created 3 DNS entries.

adfs.wingu.dk A record pointing to my ADFS server (http/https published in TMG)
crm2011.wingu.dk A record pointing to my CRM2011 server (http/https published in TMG)
*.crm2011.wingu.dk CNAME record pointing to crm2011.wingu.dk

I am using 2 certificates. *.wingu.dk and *.crm2011.wingu.dk ( the first doesn’t need to be * but since I already had it, it was just easier to use that )

After installing CRM2011 I when to Deployment Manager and chanced the Web Address’ to internal.crm2011.wingu.dk ( this will now be the internal URL meaning this can be used to logon on to CRM with Kerberos. That means going to an org internally will now be internal.crm2011.wingu.dk/ORGName but coming externally with be ORGName.crm2011.wingu.dk . This one took me a while to get right. )

image
Update 23-09-2011: Don’t use different domain names here. It will make web service requests go nuts. so for me, that would be internal.crm2011.wingu.dk in all fields.

Next we want to setup Claim Based authentication on CRM. fire up the wizard an type

https://adfs.wingu.dk/FederationMetadata/2007-06/federationmetadata.xml

As encryption certificate you need to use a certificate that is common for all CRM servers (I think ? at least that gave me some issues when deploying more than one. Ill need to get back on this later, but for now I just choose the *.crm2011.wingu.dk certificate
Update 23-09-2011: True. When CRM receives a claim from ADFS it needs to use this certificate to decrypt the tokens. This has to be the same on all frontend servers. )

Jump to the ADFS server and “Add Relying Party Trust” and type in

https://internal.crm2011.wingu.dk/FederationMetadata/2007-06/FederationMetadata.xml

Note, we are using the “internal” link here, after that add the Claim rules from the video.
Pass Through or Filter and Incoming Claim –> Pass Primary Sid –> “Primary SID”
Pass Through or Filter and Incoming Claim –> Pass UPN –> “UPN”
Transform an Incoming Claim –> Transform Windows Account Name –> Windows Account name –> Name
( Update 23-09-2011: Actually it only needs UPN )

image

if this is the first time, also go to Claims Provider Trusts and add Claim rule to Active Directory –> Send LDAP Attributes as Claim –> Send UPN from AD to Claim –> "Active Directory” –> userPrincipalName –> UPN

image

Head back to CRM2011 and now configure Internet-Facing Deployment. Domains is crm2011.wingu.dk. Using dev.crm2011.wingu.dk or crm2011.wingu.dk under Discovery Web service didn’t really seem to make much difference for me, but just to be safe I did that.

image

External domain. Again I still don’t get this one. if you type the name for an organization that already exists you will get a ton of errors and problems. If you use the default “auth.crm2011.wingu.dk” and go this is URL after you get an “404” so I can add that to my “to read up on” list, but for now I just accepted the default. auth.crm2011.wingu.dk

image

After all this testing the internal URL will properly fail. at least it did for me. Tried adding internal.crm2011.wingu.dk and adfs.wingu.dk to “trust sites” in IE, but still didn’t work. after google’ing for a while I tried adding it to “Local Intranet Zone” and then everything worked. It felt wrong but hey, if it works it must be right, right ?

WRONG! .. but took a while before I found out why and how.

Update 23-09-2011: Two things went wrong here regarding powershell. 1) on CRM properties I had not typed the same domain name in all fields. 2) UPN mappings was setup wrong.

One thing that gave me problems was the PowerShell commands and calling the CRM web services. I n the beginning I would constantly get “The Deployment Service cannot process the request because one or more validation checks failed”. You can’t see it in PowerShell but if you do it from visual studio against the web service you can see the inner exception, and I could there see the problem was authentication. If I added a username and password everything would go though, but I wanted a solution that would accept Kerberos.

I created 2 console applications. One where I had added a Service Reference and in the other I would use the CRM 2011 SDK. I need this for provisioning the service in the hosting I’m building so its critical for me to be able to point to a specific server and not “hardcoded” to a specific URL. I also need to be able to use this from a DLL and as some people might now, that can be a bit trouble some. I cant remember/reproduce all the weird and annoying errors I got, trying tons of different approaches regarding connecting to CRM. Basically what I found was I could connect if I supplied username and password, but Kerberos would only work connection go the Deployment Service if using the SDK. Everything would work from the application where I had added the URL’s as Service References but when trying to create a ConfigurationChannelFactory that loaded the app.config everything would just start failing miserably. While paying around with all this and messing around with SPN’s, I suddenly got these 2 errors.

The NetworkCredentials provided were unable to create a Kerberos credential

SOAP security negotiation with 'https://adfs.wingu.dk/adfs/services/trust/2005/kerberosmixed' for target 'https://adfs.wingu.dk/adfs/services/trust/2005/kerberosmixed' failed.

and that got me thinking that I might have screwed up something in my SPN’s. I delete them all and recreated the following SPN’s

I added a SPN for the ADFS server
setspn –A HOST/adfs.wingu.dk ADFS01
setspn –A FQDN/adfs.wingu.dk ADFS01

setspn –A HOST/internal.wingu.wingu.dk CRM201101
setspn –A FQDN/internal.wingu.wingu.dk CRM201101

(Updated 07-05. I had chosen to install ADFS as standalone. If you choose the high availability doing setup, the installer set’s the SPN for you, but instead of setting it on the computer account the SPN’s get added to the service account ADFS runs under. )

And voila, everything just worked like a charm. If testing from a browser, make sure to add adfs.wingu.dk to “Local intranet” zone. The reason for this is that internet explore thinks (and is correct) that adfs.wingu.dk is an external URL and refuses to send your credentials to the site, and hence you will see a “popup” asking for username and password. Maybe there’s a better way around this, if so I haven’t found it. I don’t care, I can control this though policy’s on the RD/XenApp servers and the MS CRM 2011 SDK works, so I’m happy.

And here is a few goodies regarding connecting to CRM though code, and using LINQ to query data in CRM too.

Imports Microsoft.Crm
Imports Microsoft.Xrm
Imports Microsoft.Xrm.Sdk

Module Module1

    Private cliDeployment As Deployment.DeploymentServiceClient
    Private cliDiscovery As Discovery.IDiscoveryService
    Private cliOrganization As Microsoft.Xrm.Client.Services.OrganizationService
    Private cliContext As Microsoft.Xrm.Client.CrmOrganizationServiceContext
    'Private linqCRM As CrmQueryProvider

    Private Sub InitializeClients(Host As String, UniqueName As String)
        InitializeClients(Host, UniqueName, "", "")
    End Sub
    Private Sub InitializeClients(Host As String, UniqueName As String, Username As String, password As String)
        Try
            Dim DeploymentURI As Uri = New Uri("https://" & Host & "/XRMDeployment/2011/Deployment.svc")
            cliDeployment = Deployment.Proxy.ProxyClientHelper.CreateClient(DeploymentURI)

            Dim Credentials As ServiceModel.Description.ClientCredentials = Nothing
            If Username <> "" And password <> "" Then
                Credentials = New ServiceModel.Description.ClientCredentials
                Credentials.UserName.UserName = Username
                Credentials.UserName.Password = password
            End If
            Dim discoveryServiceUri As Uri = New Uri("https://" & Host & "/XRMServices/2011/Discovery.svc")
            cliDiscovery = New Microsoft.Xrm.Sdk.Client.DiscoveryServiceProxy(discoveryServiceUri, Nothing, Credentials, Nothing)
            If UniqueName <> "" Then
                Dim CrmConnection As New Microsoft.Xrm.Client.CrmConnection
                If Username <> "" And password <> "" Then
                    CrmConnection = Microsoft.Xrm.Client.CrmConnection.Parse("Url=https://" & Host & "/" & UniqueName & "; Username=" & Username & "; Password=" & password)
                Else
                    CrmConnection = Microsoft.Xrm.Client.CrmConnection.Parse("Authentication Type=Integrated; Url=https://" & Host & "/" & UniqueName)
                End If
                cliContext = New Microsoft.Xrm.Client.CrmOrganizationServiceContext(CrmConnection)
                cliOrganization = New Microsoft.Xrm.Client.Services.OrganizationService(CrmConnection)
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Sub Main()
        Dim UniqueName As String = "test1"
        InitializeClients("internal.crm2011.wingu.dk", UniqueName)

        Dim request1 As New Deployment.RetrieveRequest
        request1.EntityType = Deployment.DeploymentEntityType.Organization
        request1.InstanceTag = New Deployment.EntityInstanceId
        request1.InstanceTag.Name = UniqueName
        Dim response1 As Deployment.RetrieveResponse = cliDeployment.Execute(request1)
        Dim org1 As Deployment.Organization = response1.Entity
        Console.WriteLine("Deployment Service: " & org1.UniqueName & " " & org1.FriendlyName)

        Dim Request2 As New Discovery.RetrieveOrganizationRequest
        Request2.UniqueName = UniqueName
        Dim Response2 As Discovery.RetrieveOrganizationResponse = cliDiscovery.Execute(Request2)
        Dim org2 As Discovery.OrganizationDetail = Response2.Detail
        Console.WriteLine("Discovery Service: " & org2.UniqueName & " " & org2.FriendlyName)

        Dim response3 = cliOrganization.Execute(New Microsoft.Crm.Sdk.Messages.WhoAmIRequest())
        Console.WriteLine("Organization (WhoAmI)")
        For Each res In response3.Results
            Console.WriteLine(res.Key & ": " & res.Value.ToString)
        Next

        Dim contacts = cliContext.CreateQuery(Of Contact)().ToList
        For Each c In contacts
            Console.WriteLine(c.FirstName & " " & c.LastName)
        Next

        Console.WriteLine(vbCrLf & "done.")
        Console.ReadLine()
    End Sub

End Module