Mixing SQL query and PowerShell send-mailmessage - sql-server

I've combed through the help files here and can't quite find the right combination of what I'm looking for.
Someone before my time created a PowerShell script that is used to create user accounts in Active Directory. Currently, when a new account is requested, the admin (me) runs a script that creates the AD account, then goes back to a Web-based form to enter the user name/password (also generated by that script) to close the request. Closing it through the form also kicks off an email to the requestor and two system admins with the user name and password in it.
Because it's silly to have to copy/paste anything, I've successfully added cmdlets to the script write the user name, password and other data back to the SQL table directly and close the ticket. I've also successfully added a send-mailmessage cmdlet to generate that user name/pswd email. My problem comes when I need to look up (via a SQL query) and send to the email address of the original requestor. The request form captures the user ID of the requestor, which I then use a query to find their email address from another table and define it as a variable.
$requestor = Invoke-Sqlcmd -ServerInstance [servername] -Database [dbname] -Query
"select b.email from [Table1] a left outer join
[Table2] b on a.requestedby = b.clockid where
a.accrequestid = '$reqID'"
Two things may be causing problems here. When I define that variable and then type $requestor for output, I get
PS SQLSERVER:> $requestor
email
[email#abc.com]
I may need to find a way to define that variable as just the email address value without the field header, and I'm not sure how to do that. (I'm very new to PowerShell.)
The other issue is using that variable as part of an array. Currently, my send-mailmessage cmdlet looks somewhat like this:
$PSEmailServer = "[SMTPServerName]" Send-MailMessage -From
"[EmailAddress]" -To "email1#abc.com", "email2#abc.com", "$requestor" -Subject "User
Account Info ($DisplayName)" -Body "The user account you requested
has been created."
The email will deliver to email1 and email2, but I get this error from the use of the variable:
Send-MailMessage : The specified string is not in the form required
for an e-mail address. At [FileName].ps1:381 char:1
+ Send-MailMessage -From "onlinenotification#foley.com" -To "$requestor" -Subject ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (:) [Send-MailMessage], FormatException
+ FullyQualifiedErrorId : FormatException,Microsoft.PowerShell.Commands.SendMailMessage
I have tried all combinations of single, double and no quotes around that $requestor variable, and tried sending to only the address returned by the variable. No luck.
Does anyone have any experience with something like this? I know I could go create a trigger on the SQL table to send an email instead, but I'd love to figure out what the problem is here. My guess is that it's the former issue...
Many thanks!
(The database is SQL2008R2 and PowerShell is v4.)

$requestor will contain the SQL record as an object. As you're selecting the email column in your query this will probably be an array of email addresses.
You can inspect what the $requestor object is by typing $requestor.GetType() at the PowerShell prompt.
However, at a guess I'd imagine you need to use:
($requestor.email)[0] in your Send-MailMessage command to access the string property of the returned object or create a variable for the requestor email address by doing something like:
$reqEmail = $requestor | Select-Object -ExpandProperty email -First 1

Related

Get no result from LDAP query

I am trying to filter out employees from a specific OU via LDAP.
The problem is that the OU contains spaces.
By itself, with \20 between the respective words, this OU should be resolved and be able to be found.
Furthermore, there is no CN in the respective OU.
What I have tried so far is the following:
(&(objectCategory=person)(objectClass=user)(ou=test\20user\20accounts,dc=lab,dc=local))
Unfortunately I only get an empty output.
The searchbase is missing and i dont know how to implement it in the ldap query.
With Powershell i dont have any issues to get what i want:
Get-ADObject -LDAPFilter "(ObjectClass=user)" -SearchBase "ou=test\20user\20accounts,dc=lab,dc=local" -Properties * |`
? {$_.ObjectCategory -like "cn=Person*" }| select name,objectclass,ObjectCategory | fl
I appreciate any advice :)
Thanks in advance
To search for users in an OU, set the search root of your query (sometimes called Base DN) to the OU. It cannot be done in the filter.
The memberOf attribute is used for groups, not OU's.
You do not supply enough information to make an accurate assessment.
What are you looking for within OU=Test,User,Accounts,DC=Lab,DC=local?
"I wanna get all the members of the OU Test User Accounts"
This should get all "Users" (sAMAccountType=805306368) in the container "OU=Test,User,Accounts,DC=Lab,DC=local" (With some tweaking to fit your server and credentials)
ldapsearch -D "cn=exampleuser,example.com" -w secret -h server.example.com -b "OU=Test,User,Accounts,DC=Lab,DC=local" -s sub "(sAMAccountType=805306368)"

Add a value to all users in AD

I am trying to set up dynamic distribution lists at the company I work for.
I want to use the company value in AD for a distribution list that everyone in the company needs to be part of.
Most of our users have the name of the company as the value, but after checking some users it appears that this value is not set for all users.
Is there a way to set this value for all AD users (by using powershell f.e), or get a list of users where the company value is not set to the company name?
You can use the PowerShell ActiveDirectory module, which is included in the Remote Server Administration Tools (RSAT). Details on how to install it are here.
Then you can use Get-ADUser and pipe the results into Set-ADUser. Something like this:
$badusers = Get-ADUser -Filter "company -ne 'Your Company Name'"
$badusers | Set-ADUser -Company "Your Company Name"
You could do this in one line, but I split it into two so you can inspect the $badusers collection to actually see the users that you changed (just type $badusers into the PowerShell prompt and hit enter).
It may be wise to limit it to, say, 5 or 10 users just to make sure it works the way you want before attempting to change every user. You can do this by adding -ResultSetSize 5 to the Get-ADUsers line.
This also assumes you want to change all user objects to have your company name, even administrative accounts. Keep in mind that this will stop processing users if it hits one that you don't have permission to modify. If you want to limit it to a single OU, you can use the -SearchBase parameter of Get-ADUsers, like this:
$badusers = Get-ADUser -Filter "company -ne 'Your Company Name'" -SearchBase "OU=Users,DC=example,DC=com"

How to access a key on an array that i recovered on AD with shellscript

First the question, after ill contribute on some idea im working:
Im receiving from AD some information and got an array on one of them.
I want to extract this info so i can use for next part of my project
the script:
Get-ADUser foo -Properties * | select name, department, manager
this returns me a table, ill simplify reading:
name -> foo
department -> bar
manager -> CN=foo, OU=bar, OU=fubar, OU=foobar
**disclaimer: im from BR, so it may look different for you when u receive data(if you trying to reproduce)
I want to extract The info "foo" from uptable, but i accept even "CN=foo".
::finalle
My idea is to create automation by taking AD's data and by shell putting into MSWord
There i have some fields that has autocompletion and after this ill need to somehow pass it through shell
The complete goal is
run a script that the users gives who he wants (by ID), find it and
receive the word oppening with all writen, instead of have to stay
changing the same document everytime someone needs this
Thank you guys!
I manage do get 2 commands that do the job after some time.
(get-aduser (get-aduser foobar -Properties manager).manager).name
Get-ADUser -Identity foobar -Properties manager |
Select-Object -Property #{label='Supervisor';expression={$_.manager -replace ',.*$'}}
Thanks for the help anyway

Query to LDAP on WIndows Server to get Active Directory's User

I have setup AD DS and AD LDS in Windows 2012 Server.
Requirement is to query to LDAP using Java.
I have tried this:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://55.22.44.22:53358");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
"CN=ecode,CN=Users,DC=ecode,DC=com");
env.put(Context.SECURITY_PRINCIPAL, "ecode#ecode.com");
env.put(Context.SECURITY_CREDENTIALS, "ddadadad");
DirContext context = new InitialDirContext(env);
I get the following error
Exception in thread "main" javax.naming.AuthenticationException: [LDAP: error code 49 - 8009030C: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 2030, v2580�]
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3154)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3100)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2886)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2800)
at com.sun.jndi.ldap.LdapCtx.(LdapCtx.java:319)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
I know code 49 is LDAP_INVALID_CREDENTIALS. I am not sure what to pass in
SECURITY_AUTHENTICATION parameter.
I have tried following as SECURITY_AUTHENTICATION in parameter:
CN=ecode,CN=Users,DC=ecode,DC=com
ecode#ecode.com
In Powershell when I try
dsquery user -name ecode
I get this output
CN=ecode,CN=Users,DC=ecode,DC=com
I'm not a Java developer (at least not recently) but according to the examples here, you should be doing something like this:
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "CN=ecode,CN=Users,DC=ecode,DC=com");
env.put(Context.SECURITY_CREDENTIALS, "ddadadad");
That's basically what I use successfully against Active Directory as well as a few pure LDAP servers -- the fifth line isn't right; but an unmatched parenthesis shouldn't compile so I'm assuming it's a copy/paste problem and the line is actually comment with another logon ID format that you've tried.
There are three options for the SECURITY_PRINCIPAL as Active Directory's LDAP implementation lets you bind with userPrincipalName (dsquery user -o upn -name ecode), sAMAccountName (domain\logonID but dsquery user -o samid -name ecode only returns just the logonID component of the sAMAccountName for some reason), or the fully qualified DN (dsquery user -o dn -name ecode).
If you've confirmed the ID you are using matches one of these, see if the bad password count is being incremented. Bad password count is not a replicated attribute; if you have more than one domain controller, target the one used in your LDAP connection. If the counter is incrementing, then you've got the proper security_principal and the password is being rejected (bad password or possibly a locked account)
dsquery * "Fully-Qualified-DN-Here" -scope base -attr badPwdCount -s DomainControllerUsedInLDAPBind

Saved LDAP Query Locked Out Specific OU

Currently I can do this in powershell via this script:
Search-ADAccount –LockedOut -SearchBase 'OU=location,OU=country,DC=company,DC=com' | ft Name, SamAccountName, LastLogonDate
I would rather have it in a LDAP saved query, I found this one to display all locked out accounts in the company:
(&(&(ObjectCategory=Person)(ObjectClass=User)(LockoutTime>=1)))
I have tried a number of combinations, but I can't seem to get it right. Here is one of them:
(&(&(ObjectCategory=Person)(ObjectClass=User)(memberof=OU=location,OU=country,DC=company,DC=com)(LockoutTime>=1)))
What am I doing wrong?
As information, when you create a new query, you have the option of specifying the "query root"... by drilling down with that, I was able to achieve the desired goal. I didn't have to modify the query string at all.

Resources