Converting Folder ID from EWS to Exchange Cmdlet's Identity - exchange-server

Using Managed EWS 2.0, I'm trying to write some code to create, delete and mail-enable Public Folders on Exchange 2010. However, according to Exchange MVP Glen Scales, mail-enabling a folder is only possible using PowerShell cmdlets, which can be invoked from my C# code. So far, so good.
However, I'm a bit confused when mapping between my EWS Folder objects (which have a FolderId) and PowerShell's Enable-MailPublicFolder cmdlet, which expects a GUID or a Folder Path as identity parameters. I'm not sure how to map between the two.
EWS has a ConvertIDs method, but that seems to be able to generate various formats (EwsId, EntryId, OwaId) which don't seem relevant to PowerShell.
Apart from manually generating a Folder Path from my given folder, which is easy but feels clunky given that I have an explicit identifier for the folder, is there a way to convert my Folder ID to a format usable by the Exchange Cmdlets?

Ok, with the help of Glen Scales I got this to work. It seems that PowerShell's PublicFolderIdParameter type (the type of the Identity parameter) accepts a sequence of Hexadecimal characters representing the EntryID. So to translate an EWS ID to a PowerShell-accepted ID, we can use this code:
Folder myFolder = Folder.Bind("whatever");
var ewsId = new AlternatePublicFolderId(IdFormat.EwsId, myFolder.Id.UniqueId);
var hexId = _service.ConvertId(ewsId, IdFormat.HexEntryId) as AlternatePublicFolderId;
string idForPowerShell = hexId.FolderId;

Related

How can I encrypt the parameters of a panel in the same way as Genexus?

We need to encrypt a string in the same way that Genexus (17U10 and csharp if it's important) encrypts the parameters of a panel using the site key.
To better understand, the first is the url with unencrypted parameters, the second is the same url with parameters encrypted via site key
http://localhost/TestVersione17U10.NETFrameworkEnvironment/webpanel3.aspx?par1=hello
http://localhost/TestVersione17U10.NETFrameworkEnvironment/webpanel3.aspx?ROndRLvw5t80mViNc0wdKO7XYc-OgWL61k9lDimrqI0
Reading in the wiki, I believe that genexus uses the key stored in the application.key file and uses the twofish algorithm.
7E2E22D26FF2989E2444852A85E57867
This is the key I have in the file, I tried in every way to get the second string starting from the first, but without success.
The native Encrypt64 method gave no results, the generated string is different.
I also noticed that the same parameters are encrypted differently when I call another panel, so I believe it somehow uses the panel name as well.
( webpanel2.aspx?mY8XtkZ-3eBJKsDIFk-zX3DP2PuQC2LHIkqwFtE1CZw )
What am I doing wrong? Is the key wrong? Do you use any other way to encrypt other than Encrypt64?
I’m not sure what you really want to implement. I mean, do you want storage this link? Do you need it in order to call from a “non GX application”?
Anyway, as you said, object name is included in the algorithm to URL encryption.
This algorithm is not available as a “function” to be used by GX developers directly. However, there are two ways to do something like that in Genexus:
To use “link” function. https://wiki.genexus.com/commwiki/servlet/wiki?8444,Link%20Function
To use non standard functions. Suppose you have “webpanel3.aspx par1=hello,par2=world” then the code could be something like:
&GXKey = GetSiteKey()
&GXEncryptionTmp = "webpanel3.aspx"+UrlEncode("hello”) + "," + UrlEncode("world")
&EncryptedParms= "?" + UriEncrypt64( &GXEncryptionTmp + CheckSum(&GXEncryptionTmp, 6), &GXKey))
Note: You must enable “non standard functions” (https://wiki.genexus.com/commwiki/servlet/wiki?8013,Standard%20Functions%20property%20at%20Object%20level)
If you need to call from a non GX application, there are to options:
To use a GX generated program as “proxy”. This object receive not encrypted parms and returns the encrypted URL or directly encrypt the parameters and call the corresponding object
To explore object generated in order to mimic that code in your solution/code. This includes exploring GXClassses (i.e. https://github.com/genexuslabs/DotNetClasses)

Alternative for Folder.WellKnownFolderName for older Exchange versions

I use Folder.WellKnownFolderName to detect folder type, but it was introduced only in Exchange 2013. Also it doesn't work with "Clutter" folder. Can i use another Folder property to determinate exchange folder type?
Take a look at the FolderClass property. That tells you the type of folder (Mail, Calendar, etc.).
Iterate through all the WellKnownFolderNames you care about, and fetch the corresponding Folders individually by passing Folder.Bind a FolderId created with the constructor that takes a WellKnownFolderName. The FolderId of the returned Folder will have its unique ID set. Then just keep track of the FolderId-to-WellKnownFolderName mapping.

How can I add a local group to Publishing Point with VBScript?

I'm trying to figure out how to add a local group to an (On-Demand) Publishing Point, with vbscript.
The group just needs read access to it. The group has (of course) been created first.
System: Windows Server 2008 R2 x64 with Media Services 2008 (for R2). It's not a Domain Controller, there's no Active Directory.
Context: Running a media server with one Pub. Point per movie, and use the group to allow/deny access to that Pub. Point / movie on a per-user basis.
I can add the group manually, but I would really like to do it with a (vb)script.
To do it manually:
(first create a local group).
In Server Manager, click the on-demand Publishing Point, Properties tab, Authorization, WMS Publishing Points ACL Authorization (which of course has to be enabled), right-click it - choose Properties.
Strangely, Groups are by default not enabled in Object Types, so one has to specifically enable them to be able to add the group.
The closest example I've been able to find is this: (it's in VB.Net)
http://msdn.microsoft.com/en-us/library/dd875036%28v=VS.85%29.aspx
My (almost-working) script so far:
Dim Server
Dim ODPubPoint
Dim Plugin
Dim ACLCheckAdmin
Dim AccessCtrlList
Dim objACE
' Create a new WMSServer object.
Set Server = CreateObject("WMSServer.server","localhost")
' Create a new ODPubPoint object.
Set ODPubPoint = Server.PublishingPoints.Item("supersizeme")
' Retrieve the plug-in to be configured.
Set Plugin = ODPubPoint.EventHandlers.Item("WMS Publishing Points ACL Authorization")
' Retrieve the custom interface of the plug-in.
Set ACLCheckAdmin = Plugin.CustomInterface
' Retrieve the list of access control entries.
Set AccessCtrlList = ACLCheckAdmin.AccessControlList
' Create an object to be able to add to the access control list.
Set objACE = CreateObject("AccessControlEntry")
objACE = AccessCtrlList.Add("MEDIESERVER\hest", 16 )
The group does get added, but the script dies with an error:
ppaddgroup.vbs(27, 2) Microsoft VBScript runtime error: Object doesn't support this property or method.
In the VB.Net example it says WMS_ACCESS_CONTROL.WMS_ACL_ALLOW_ALL which I have no idea how to convert from VB.Net to VBScript. I thought it was just a constant, but apparently not.
(and I just want to allow read access, as in WMS_ACL_ALLOW_READ ).
I found the constants on this page:
http://include.wutils.com/com-dll/constants/constants-WMSServerLib.htm
Can anyone come up with the correct way to add a group to a publishing point?
Per greylion's previous edit:
The last line needs to be:
Set objACE = AccessCtrlList.Add("MEDIESERVER\test", 16 )
For some reason, I was convinced that the final act of adding the
group was not supposed to have a "Set" in front. I thought it was only
for creating or defining objects, but apparently it's also for filling
them with actual data. Annoyingly, it almost worked with "Set"
missing, which led me to think I just had some minor detail wrong, but
no way to know what it was.
Mental note: Filling an object with data is NOT like setting a
variable or constant.

Find account GUID, and Select it back using Object GUID

I am trying to select a unique identifiers for accounts from Active Directory. I found that "objectguid" attribute do identify a user uniquely, but my problem is that I don't know how to convert the retrieved value into a readable format. And then be able to select a user back using this value.
I am using spring ldap libraries, right now the "objectguid" return a char[] (15 element)
So, Does any one knows any thing that can help?
(Note, I can't use SAM Name attribute)
Thanks,
See here. It appears there are two string formats: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, which you can get via new BigInteger(0, (byte[])attr.get()).toString(16), and XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, which is the same thing plus punctuation.

How to quickly find a sharepoint document library by id?

Given the SPList.ID and a site collection (or an SPWeb with subwebs), how do I quickly find the document library with the given ID?
I can recursively enumerate through all webs and perform a web.Lists[guid] on each one of them, but there might be thousands of subwebs in my case, and I'm looking for a realtime solution.
If there is no way to do this quickly, any other suggestions on how to uniquely identify a document library? I could store the full path (url), but the identification will be publicly visible and I don't feel very comfortable giving away our exact SharePoint document structure like that. Should I resort to maintaining a manual ID <-> library mapping in a separate list?
I vote for the manual ID -> URL pair matching in a top-level, well-known list that's visible only to the elevated privileges account.
Since you are storing the ListID somewhere, you may also store the WebId. Lists are opened by the context SPWeb always, so if you go to:
http://toplevel/_layouts/ListGeneralSettings.aspx?ID={GUID1} // OK
http://toplevel/sub1/_layouts/ListGeneralSettings.aspx?ID={GUID1} // Wont Work (same Guid)
Having the WebId and ListId you can simply:
using(SPWeb subweb = (new SPSite("http://url")).OpenWeb(new Guid("{000...}")))
{
SPList list = subweb.Lists.GetList(new Guid("{111...}"), true);
// list logic
}
MS does not support this :)...
But take a look at this for giggles: http://weblogs.sqlteam.com/jhermiz/archive/2007/08/15/60288.aspx
If you have MOSS Search available, then it might help, depending on the lag you have between these lists getting created and needing to search for them. You could probably map list id as a managed property and do a quick search for list objects with the id in question.
For lots of classes of problems it seems like search is the fastest way to rip through huge sets of data. In fact if this approach worked for you, you really wouldn't even need to know the site collection up front. Don't have access to any of my MOSS environments at the moment, so can't verify this will work though.

Resources