get AD group description - vba

I need a VBA function to return the description of AD groups.
Returning the value with Powershell would be easy:
Adgroup = "abc"
strCommand = "Powershell.exe [environment]::CurrentDirectory='C:\Windows\System32\WindowsPowerShell\v1.0'; start-job -ScriptBlock{Get-ADGroup -identity " & Adgroup & " -Properties Description | select Description | ft -HideTableHeaders} | wait-job | receive-job"
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)
strOutput = WshShellExec.StdOut.ReadAll
Debug.Print strOutput
This code returns the correct output, however it has the downside of popping up the PS window.
I found a solution that can hide the PS window, however when I use it, the Antivirus software blocks the script. Since I do not want to mess with it, I need a different solution.
What would be a good non Powershell approach for this?

Thank you Divin3 and Tomalak for your valuable discussions. Posting your discussions as answer to help other community members.
Access the AD directly in VBA. You can use ADSI (Active Directory
Service Interface) for the same.
Reference:
http://exceldevelopmentplatform.blogspot.com/2017/10/activedirectory-with-vba-part-4-adsi.html,
https://stackoverflow.com/questions/21110232/getting-ad-details-based-on-username/21113591#:~:text=LDAP%20URIs%20require,some%20time%20ago.

Related

Hand Masterpassword to keepassxc-cli (or retrieve entry from keepassxc by vba)

I tried a lot with the keepassxc-cli manpage but was not able to solve my seemingly simple task. I couldn't find real examples as well.
I want to invoke keepass-cli from a vba-script (I have reasons ;-) ) and retrieve a username/password (can be in two steps) to use in a script. I can copy the password on the shell when typing:
$ keepassxc-cli clip "path\to\db" "db entry name"
Then I am prompted to type in my master password.
However I would like to keep the user from the cli and rather have an input in my original script so the user can type the master password there and the password is handed over seamlessly.
In short I am looking to a way to enter something along the lines
$ keepassxc-cli clip "path\to\db" "db entry name" -master "my secret master password"
NB: keepassxc has the option --pw-stdin which keepassxc-cli seems to be missing. (Then I could use this answer)
Security level overall is quite low, however I don't want to put a database pw (for read access) verbatim into the script (as it is done by my predecessor), and in a company environment I cannot install plugins for keepassxc or similar.
Any pointers to some examples of keepass-cli examples are also very much appreciated.
Your post is tagged with VBA, and your answer looks like a linux shell?
I couldn't get that to work using CMD, invalid credentials errors etc. (although I didn't try all that hard)
Powershell handles it just fine though.
Assumed you wanted VBA, the paths to the cli and database would need to be changed.
Sub ClipPassword(Name As String, Master As String)
CreateObject("WScript.Shell").Run "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden -Noninteractive -NoProfile -Command " & Chr(34) & Chr(39) & Master & Chr(39) & " | &" & Chr(39) & "C:\Path\To\KeePassXC-2.7.4-Win64\keepassxc-cli.exe" & Chr(39) & " clip " & Chr(39) & "C:\Path\To\Passwords.kdbx" & Chr(39) & " " & Name & Chr(34)
End Sub
The command run in powershell is essentially the same as your answer
"masterpassword" | &keepasxc-cli clip "database" account
Reading this issue on keepassxc's github let me realise that using echo also helps here:
$ echo notsosecretpassword | keepassxc-cli clip "path\to\db" "db entry name"

Shell.Execute in VBA is not doing anything

I am trying to use powershell to extract some files from a zip folder located on a drive where I only have read access to my desktop in a temp folder where I can do whatever I like to them.
Using the code below I get no errors but the powershell code just does nothing.
Am I missing something?
Sub unzip_test()
Dim myshell As Shell32.Shell
Set myshell = New Shell32.Shell
Dim args As String
args = "Expand-Archive -LiteralPath " & "'C:\Users\user1\Desktop\TEMP\examplezip.zip'" & " -destinationpath " & "'C:\Users\user1\Desktop\TEMP\tester'"
'Debug.Print (args)
myshell.ShellExecute "powershell", vargs:=args
End Sub
The debug.print prints Expand-Archive -LiteralPath 'C:\Users\user1\Desktop\TEMP\examplezip.zip' -destinationpath 'C:\Users\st11524\Desktop\TEMP\tester'
Also, I have "Microsoft Shell Controls and Automation" checked in my references.
It should work. I think the problem is somewhere in the Expand-Archive call, but you can't see the answer.
The quick fix is to add -NoExit to your call, like this
args = "-NoExit Expand-Archive -LiteralPath " ...
This will allow you to read the error before it closes, but you can't read it from your code. If you need that, have a look here
After testing this on another computer I've come to the conclusion that this is a permissions thing. My personal computer runs the script just fine where my work computer won't. I don't see anything wrong with the code listed above so I will consider this issue resolved.

SSIS Element cannot be found in a collection (but I have them all listed!)

I'm getting a persistent error:
The element cannot be found in a collection.
This error happens when you try to retrieve an element from a collection on a container during execution of the package and the element is not there.
I've checked, double and triple-checked my variable listings in the Read-Only and Read-Write variables in my Script task.
I've debugged it to death and gotten input from another programmer here who couldn't spot the issue either.
I've also researched to no end.
Does anyone see anything wrong with my code?
Script Task code:
Public Sub Main()
Dts.Variables("User::strMailBody").Value = "Thank you for submission. For your convenience, we are including the last four of the HICN# and the Name on the application(s) we have received* from you." _
& vbNewLine & vbNewLine & "Here are the following: " & vbNewLine & vbNewLine
Dts.Variables("User::strMailBody").Value = Dts.Variables("User::strMailbody").Value.ToString() & vbNewLine & Dts.Variables("User::strListing").Value.ToString()
Dts.Variables("User::strMailBody").Value = Dts.Variables("User::strMailBody").Value.ToString() & vbNewLine & vbNewLine & Dts.Variables("User::strFooter").Value.ToString()
If Left(Dts.Variables("User::strAgentID").Value, 2) = "TX" Then
Dts.Variables("User::strSubject").Value = "ACME Health Plans Confirmation: Total "
Else
Dts.Variables("User::strSubject").Value = "ACME2 Baptist Health Plans Confirmation: Total "
End If
Dts.Variables("User::strSubject").Value = Dts.Variables("User::strSubject").Value.ToString() & Dts.Variables("User::lngCountAgent").Value.ToString() & " " & "[RESTRICTED: CONFIDENTIAL]"
Dts.Variables("User::DateSent").Value = Now()
Dts.Variables("User::UserSent").Value = "SSIS"
Dts.TaskResult = ScriptResults.Success
End Sub
For anybody else struggling with this issue the resolution for me was as follows: (note I am NOT using User:: when getting variable values within my script task)
On the package Properties I hadn't included the variables as ReadOnlyVariables
You'll need to set your newly added variables as follows:
Right click on the package and select Edit
In the Script section click on ReadOnlyVariables or ReadWriteVariables (depending on your how you want your variables behave)
Check the check-box beside the variables you wish to use in your script task
Click Ok to save your changes
Hope this helps
I just had the same issue and unable to find the problem for ages. I found that the reason for the error was that I had missed one of the colons between "User" and the variable name.
I had this (which caused the error):
string FileName = UserVariables["User:CurrentFileName"].Value.ToString();
when I should have had this:
string FileName = UserVariables["User::CurrentFileName"].Value.ToString();
just in case anyone else has the same problem :)
Ohhh.........man. It's amazing how you can stare at this stuff and miss something stupid, for hours.
strFooter was missing in the listing.
ALL SET NOW. Sincere thanks to those who looked and commented. Eric, thanks, I'll remember that as sometimes I will probably need to use C insatead of VB (haven't yet but will).
Had a similar issue, after a lot of debugging, realized that the variable naming convention should be User::varname and NOT USER::varname
I guess c# is very case sensitive.
Hope this helps and saves you lot of your valuable time :-)
a) Right click on the script task and choose edit
b) Locate the Read or Read/Write variables properties in the list.
c) Click on the property and the variable you wish to access in the script task.
Another variation on "have been staring at the screen for too long to see the typo". In my case, I got the same error by mixing up the syntax between Project Params and User variables, and adding a $ sign in front of User.
error :
string varA = (string)Dts.Variables["$Project::ParamA"].Value
string varB = (string)Dts.Variables["$User::ParamB"].Value
corrected :
string varA = (string)Dts.Variables["$Project::ParamA"].Value
string varB = (string)Dts.Variables["User::ParamB"].Value

Get Currently Logged in username

I am trying to get the logged in username of the user by using VBS.
I tried some codes which works when I run the script directly (Double Clicking it)
Set wshNetwork = CreateObject("WScript.Network")
strUser = wshNetwork.Username
WScript.Echo "Current User: " & strUser
However, what I need to do is to use CMD to run a scheduled task using the AT command.
When it ran, the username would be the computer's name instead of the logged in user.
This problem also occurs when I run CMD as administrator and use wscript to run the script.
Is there any way to bypass this context and get the logged in user instead of the one that runs the script?
The command
query session console
should provide what you need
For an easier to parse
quser console
EDITED - Included sample vbs code
Dim strCmd
strCmd = "cmd /q /c ""quser console | find /i ""console"" "" "
Dim buffer
buffer = WScript.CreateObject("WScript.Shell").Exec(strCmd).StdOut.ReadAll()
Dim c, consoleUserName
c = InStr(buffer,"console")
If c > 2 Then
consoleUserName = Trim(Mid(buffer,2,c-2))
Else
consoleUserName = ""
End If
WScript.Echo consoleUserName
I suggest you execute the command
set
from the prompt. It may reveal a few items that are set in the environment that may be of interest.
set user
will censor the list so that only variables that start user will be displayed.

Possibility of VB.net and VBScript

Is it possible to include in a VB.net 2008 Project a VBScript (test.vbs) and run it if its while the processing necessary? But the main thing is it should be possible to BUILD just one .exe.
If so, can you also receive values / arguments from the VBS file?
Here is an example, although it's pointless, but it is used for unterstanding:
VB.net -> exe is running
the exe runs please_find_the_coputername.vbs
The script please_find_the_coputername.vbs -> obtained the computer name and sends this variable to VB.net
VB.Net displays the computer name via Msgbox().
Note: I know that I can read out the computer name with VB.net but this example is only for understanding my questions.
Edit:
HI #maxedev thank you for your answer.
Wow.. its nice trick.
But I want only to do this VBScript code in VB.net:
Dim strComputer
strComputer = "LP-BKR"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
Wscript.Echo "Logged-on Domain: " & objComputer.Domain
Wscript.Echo "Logged-on UserName: " & objComputer.UserName
Wscript.Echo "Logged-on ComputerName: " & objComputer.Name
Next
set objWMIService = Nothing
set colComputer = Nothing
I searched the whole day to get the same Value... but didn't find anything. That's why I decide to do that in this way. But if I think, the trick with clipboard is risky. It pushes the still clipboard text away. How can I realize it?
I'm not sure exactly what you're trying to accomplish, but you could write to a text file and then read it through vb.net - or you could do something like this post to use the clipboard to pass info ie :
VBS:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo hello world | clip", 0, TRUE
VB.NET:
MessageBox.Show(Clipboard.GetText)
--shows "hello world"
One solution would be to add a reference to the MS Script Control:
http://msdn.microsoft.com/en-us/library/aa227400(v=vs.60).aspx
Using that, you can add literally add code (VBScript) with the AddCode() method then run it and get the output back. I have a tiny example here.
Windows automatically provides the information you're looking for in environment variables:
%USERNAME% -> username of the logged in user
%USERDOMAIN% -> WINS name of the domain the user is logged into
%USERDNSDOMAIN% -> FQDN of the domain the user is logged into
%COMPUTERNAME% -> hostname of the computer