Desktop productivity for business analysts and programmers

Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 7
Accepted Solution

Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

I've been experimenting with Chris Hemedinger's scripts for using powershell to connect to a SAS workspace and run SAS jobs ( Using Windows PowerShell to connect to a SAS Workspace server - The SAS Dummy). That works but requires your loginname and password to be included in the script, which I'd like to avoid if possible.

It should also be possible to connect using the "CreateObjectByLogicalName" method. There's an example here (using Python):

Example of how to use SAS Workspace APIs to upload a file to a remote SAS session. Uses SAS Language...

The main section:

# create the Integration Technologies objects

objFactory = win32com.client.Dispatch("SASObjectManager.ObjectFactoryMulti2")

# these xml files can be created using the SAS Integration Technologies Configutation Utility

objFactory.SetMetadataFile( "C:/path/to/serverinfo.xml" , "C:/path/to/userinfo.xml" , False )

# create a connection to the SAS Workspace Server

objSAS = objFactory.CreateObjectByLogicalName( "SASApp - Logical Workspace Server" , "" )


I've used ITConfig to create a default connection to the metadataserver. That creates "oms_serverinfo2.xml" and "oms_userinfo2.xml" in "%USERPROFILE%\AppData\Roaming"\SAS\MetadataServer", the latter contains my password in encrypted form.


In Powershell, I create objFactory using the syntax from Chris's examples:

$objFactory = New-Object -ComObject SASObjectManager.ObjectFactoryMulti2

If I understand the documentation, I should be able to connect without pointing to my metadata but I've defined that just to be sure

$objFactory.SetMetadataFile( "<path>\oms_serverinfo2.xml" , "<path>r\oms_userinfo2.xml" , $FALSE )


Now, I should be able to create a workspace object using:

$objSAS = $objFactory.CreateObjectByLogicalName("SASApp - Logical Workspace Server" , "" )

This doesn't work though, I get an error:

Exception calling "CreateObjectByLogicalName" with "2" argument(s): "<connectionAttempts>

    <connectionAttempt>

        <description>Cannot locate an identity in metadata for the specified identity id ().</description>

        <status>0x80042102</status>

        <saslogin></saslogin>

        <sasmachinednsname></sasmachinednsname>

        <sasport>8591</sasport>

        <sassecuritypackage>Negotiate</sassecuritypackage>

        <sassecuritypackagelist>Kerberos,NTLM</sassecuritypackagelist>

        <sasclassid></sasclassid>

        <sasprogid>SAS.Workspace.1.0</sasprogid>

        <sasserver>SASApp - Workspace Server</sasserver>

        <sasdomain>DefaultAuth</sasdomain>

        <threadid>2280</threadid>

        <sasauthenticationservice>Host</sasauthenticationservice>

    </connectionAttempt>

</connectionAttempts>"

At line:1 char:48

+ $objSAS = $objFactory.CreateObjectByLogicalName <<<< ("SASApp - Logical Workspace Server" , "" )

    + CategoryInfo          : NotSpecified: (Smiley Happy [], MethodInvocationException

    + FullyQualifiedErrorId : ComMethodTargetInvocation

The server doesn't seem to be able to find who I am. Does anyone know what I might be doing wrong here?

The few examples I've been able to find using "CreateObjectByLogicalName" use two arguments, the server's logical name and an empty string. The SAS documentation though, specifies 4 arguments:

SAS(R) 9.4 Integration Technologies: Windows Client Developer's Guide

So I've also tried:

$objSAS = $objFactory.CreateObjectByLogicalName("SASApp", $TRUE, "SASApp - Logical Workspace Server" , "")

In that case, I get an error

Cannot find an overload for "CreateObjectByLogicalName" and the argument count: "4".

At line:1 char:48_te

+ $objSAS = $objFactory.CreateObjectByLogicalName <<<< ("SASApp", $TRUE, "SASApp - Logical Workspace Server" , "" )

    + CategoryInfo          : NotSpecified: (Smiley Happy [], MethodException

    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

That sounds like I just shouldn't be using 4 arguments.

Hope someone can help with this. The SAS server runs SAS 9.4, the server itself is Windows 2008 R2.


Accepted Solutions
Solution
‎07-09-2014 08:52 AM
Community Manager
Posts: 2,696

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

You might have better luck by looking at my C# example for .NET.  It's described here:

  Build your own SAS client app with Microsoft .NET - The SAS Dummy

The code is on GitHub, and the specific connection logic is in the SasServer class in this C# file. In that example, you can see how we can leave the user/pw out by specifying "Negotiate" for the BridgeSecurityProtocol -- but this assumes that you've configured your environment for single-signon/integrated Windows authentication.

Chris

View solution in original post


All Replies
Frequent Contributor
Posts: 118

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

The good news is that i can recreate your problem in my environment (SAS 9.3, Windows 7 x64) too.

So i guess this is a general bug in the SAS IT Client.

The documentation file sasoman.chm in the IT Client folder !SASHOME\x86\Integration Technologies only knows the 2 argument version of the method CreateObjectByLogicalName. There is a CreateObjectByLogicalNameAndLogins method with 5 arguments which has a similar signature to the web documentation (http://support.sas.com/documentation/cdl/en/itechwcdg/64888/HTML/default/viewer.htm#p05uy6cy21o83vn1...). IMHO the web documentation is totally wrong in this case.

As a side note: welcome to the SAS IOM hell!

It is poorly documented, many documented features do not work as expected and many important features are not documented. The only solution for these problems is a lot of trial and error coding.

Back to your problem:

accourding to the error message

<sassecuritypackage>Negotiate</sassecuritypackage>

<sassecuritypackagelist>Kerberos,NTLM</sassecuritypackagelist>

the IT client tries to connect to the server using the integrated windows authentication method and not the user/password combination. Maybe the Workspaceserver needs to be reconfigured with the SAS Management Console to use Security package "Username/Password":

Can you describe what you want to achieve after you have connected to the server?

Maybe my PowerShell commandlets (http://sourceforge.net/projects/cmdlets4sas/) already cover your needs.

Greetings,

Andreas

Occasional Contributor
Posts: 7

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

Hi Andreas,

At the least, "sasoman.chm" cleared up the "4 vs 2 arguments" issue. If you look in the index, there are two entries for "CreateObjectByLogicalName" (and most other "create" methods), with 4 arguments for "ObjectFactory" and with 2 arguments for "ObjectFactory2".

What I want to do is to run SAS programs in batch. I can do that now using VBScripts that create an "Enterprise Guide" object (also from posts by Chris Hemedinger) but I'd prefer to bypass EG and create a workspace object directly. I've modified the VBScript to do that but it requires that userid and password are included in the script and that's not a good idea from a security point of view. "CreateObjectByLogicalName" seemed like what I was looking for but I suspect you're right and that the server is configured for integrated windows authentication.

Does anyone know how to create a Workspace object without including the user password?

Thanks for your help Andreas!

Frequent Contributor
Posts: 118

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

The best practice to run SAS programs in batch is to run the program directly on the server.

You can start a new SAS session and execute a program with some simple batch files (.bat in Windows, .sh in Linux/Unix). These batch files are usually called by a scheduler like LSF or UC4.

If you want to keep the control of the execution at the client side you might want to take a look at the examples #1 and #4 here: Cmdlets4Sas / Wiki / Connect-SasWorkspaceServer

#1 shows how to use the integrated windows authentication

#4 shows how to prompt the user for login credentials

Good luck!

Solution
‎07-09-2014 08:52 AM
Community Manager
Posts: 2,696

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

You might have better luck by looking at my C# example for .NET.  It's described here:

  Build your own SAS client app with Microsoft .NET - The SAS Dummy

The code is on GitHub, and the specific connection logic is in the SasServer class in this C# file. In that example, you can see how we can leave the user/pw out by specifying "Negotiate" for the BridgeSecurityProtocol -- but this assumes that you've configured your environment for single-signon/integrated Windows authentication.

Chris

Occasional Contributor
Posts: 7

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

Thanks Chris, "negotiate" did the trick!

For anyone else sweating in IOM Hell, here's what works for me:

' force declaration of variables in VB Script

Option Explicit

Dim objFactory, objServerDef, objSAS, program, log

Set objFactory = WScript.CreateObject("SASObjectManager.ObjectFactoryMulti2")

Set objServerDef = WScript.CreateObject("SASObjectManager.ServerDef")

objServerDef.MachineDNSName = "SASServer" ' SAS Workspace node

objServerDef.Port = 8591 ' workspace server port

objServerDef.Protocol = 2 ' 2 = IOM protocol

'This assumes that you've configured your environment for single-signon/integrated Windows authentication.

objServerDef.BridgeSecurityPackage = "Negotiate"

' Class Identifier for SAS Workspace

objServerDef.ClassIdentifier = "440196d4-90f0-11d0-9f41-00a024bb830c"

' create and connect to the SAS session

Set objSAS = objFactory.CreateObjectByServer("SASApp",True,objServerDef,"","")

program = "ods listing; proc means data=sashelp.cars mean mode min max; run;"

' run the program

objSAS.LanguageService.Submit(program)

Dim loglines

loglines=""

do

    loglines=objSAS.LanguageService.FlushLog(1000)

    wscript.echo loglines

loop while Len(loglines) > 0

objSAS.Close()

Occasional Contributor
Posts: 7

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

I spoke too soon Smiley Sad.

The negotiate method does work to the extent that I can connect to the SAS server and e.g. create data from scratch or use builtin datasets. But I'm not recognized as my userid so I can't include files or define libnames to data I have access too. Complicated.

Community Manager
Posts: 2,696

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

For IWA to work, your identity still needs to exist in SAS Metadata.  You need your IWA "login" to be associated with your User object in SAS Metadata, and thus have access to your permitted resources.

If your SAS environment is not truly administered for IWA, then you might be stuck having to provide credentials in a script.  You might be able to create a more sophisticated script that pulls cached credentials from your SAS metadata profile files in the %APPDATA% area, but you'll still have to transmit them somehow.

Chris

Occasional Contributor
Posts: 7

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

Well, the real disappointment was that a batch run over VPN was just as slow with a script based on a Workspace object as with a script based on an EG object. I'd hoped that using a Workspace object would avoid some of the overhead involved with EG but that doesn't look like it's the case.A fairly simple job took over a minute using the Workspace script over a VPN connection versus 5 seconds on the office network using the EG script.

Now I know how the Dutch team feels after losing from Argentine :smileycry:.

Trusted Advisor
Posts: 1,056

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

A number of discussions are on the forums about using EG over remote / VPN connections. You might look them up, and see if anybody has a resolution to your issue.

I'm working over a remote Citrix connection, and I can literally count Mississippis while I wait for the characters to appear when I start touch typing...I feel your pain!!

Tom

P.S. There's always 2018!

Occasional Contributor
Posts: 7

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

We used to have the problem of the screen not keeping up with our typing but IT upgraded our VMWare system and it works great now. I can get good performance with my EG batch script if I run it from an editor located on the company intranet. Performance is bad though if run the editor from the hard drive on my laptop. I use PSPad as editor, it doesn't need an install program so I can put it on my local network share and run it from there when I'm using VMWare.

Community Manager
Posts: 2,696

Re: Using "CreateObjectByLogicalName" to connect to a remote SAS Workspace

Since you've got your own script now, you could add some timings to see exactly where the bottleneck is.  Is slow to make the connection? Run the code? Or retrieve the results? 

It might be simply academic, since perhaps there isn't anything you can do to help with it.  But it might provide you some news you can use....

Chris

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 11 replies
  • 1034 views
  • 6 likes
  • 4 in conversation