Error that method AppendChar() not found. It's in the docs.
ObjectClrOption("useany","System")
oSS = ObjectClrNew('System.Security.SecureString')
Message("Secure String Length",oSS.Length)
oSS.Clear()
oSS.AppendChar('T')
As has been mentioned before the CLR uses a method's signature to identify a method. This is necessary because the CLR is object based and follows the principles of object-oriented programming. In object-oriented programming, methods can be overloaded so a method's parameter types are used as part of a method's signature.
In the vast majority of cases, WinBatch automatically converts method parameters to the correct mscorelib types for you by asking the mscorelib for the appropriate type interface for the variant type before making the method call.
In this case, the CLR expects the method "AppendChar" to have a Unicode character as its only parameter. A single Unicode character is not the same type as a Unicode string. The CLR cannot find the method because there is no method "AppendChar" that takes a string as its only parameter.
Unfortunately, MSFT doesn't provide a way to consistently convert between a variant and a Char mscorlib struct type so the method call fails because the method will not accept any variant value that WinBatch passes to it. There is no direct conversion between a bstr or int variant and a Char struct. You could call it a bug in MSFT's interfaces into the CLR I suppose but that doesn't help solve the problem. You can, however, get a more descriptive error message by casting the parameter to the correct type:
oSS.AppendChar(System.Char:'T')
This produces an Invalid Parameter error message that more accurately describes the reason for the failure in this case. Another method accepting the Char type might actually work using this technique. It depends on the vagaries of the assembly you are calling into.
Typecasting is a technique to keep in mind when you encounter a method not found error. It will either resolve the issue or at the very least give you are a more specific error message.
This approach doesn't always work for miscreant types but it does seem to work for "System.Char":
ObjectClrOption("useany","System")
oSS = ObjectClrNew('System.Security.SecureString')
Message("Secure String Length",oSS.Length)
oSS.Clear()
objChar = ObjectClrNew('System.Char')
ObjChar.Parse('T')
oSS.AppendChar(ObjChar)
Message("Secure String Length",oSS.Length)
and now the second half, re-displaying the securestring as plain text. There is obviously another conversion step needed, or do I need to run another for...next
string="GameofThrones"
ObjectClrOption("useany","System")
oSS = ObjectClrNew('System.Security.SecureString')
Message("Secure String Length",oSS.Length)
oSS.Clear()
For i = 1 To Strlen(string)
objChar = ObjectClrNew('System.Char')
ObjChar.Parse(StrSub(string,i,1))
oSS.AppendChar(System.Char:ObjChar)
Next
n = oSS.Length
Message("Secure String Length",n)
oPS = ObjectClrOption("useany",'System.Management.Automation')
oPS1 = ObjectClrNew('System.Management.Automation.PSCredential','testing',oSS)
pw = oPS1.GetNetworkCredential().Password
Message("Secure String Text",pw)
oSS=0
oPS=0
oSS=0
Exit
Couldn't tell you. I was under the impression that Windows encrypts system passwords in one direction so that you can't get the plain text version but I wouldn't know if that applies in this case. The "SecurePassword" method seems to return something which makes sense since you are setting a secure password and not a plain text password on the object.
pw = oPS1.GetNetworkCredential().SecurePassword
Message("Secure String Text Length",pw.Length)
It's typo time again. I changed the phrase, "but I would know if that applies in this case" to "but I wouldn't know if that applies in this case" in the above post. Hopefully, the reply now makes a little more sense...
NP. I was trying to replicate a simple PS script which seems to indicate that the Password property can decrypt the secure string
$secret = Read-Host -Prompt 'Enter Keypass' -AsSecureString
[System.Management.Automation.PSCredential]::new('hehe',$secret). GetNetworkCredential().Password
MSFT documentation indicates the "Password" property returns a "SecureString". It also states that the "SecureString" class is not visible to COM and the class should not be used in new development.