Problem with function calling function in PowerShell - powershell

I have two functions:
CreateComputer-Group
CreateCoomputer-Role
Once first function executes then GroupCreated in first function is used in second function to create computer role. How can I make sure first function execution is completed and then only second function to execute.
Here is the code:
$global:usergroup = "TACACS Admins"
$global:computerrole = "123413-NPARC"
$global:zone = "AWS"
$username = "<>"
$password = "<>"
[String[]] $global:HostServers = 'smp001-01','sl1ps01-13-8'
#[String[]] $global:HostServers = $hostServer.Replace("'","").Split(",")
Import-Module ActiveDirectory
Import-Module Centrify.DirectControl.PowerShell
$Password = ConvertTo-SecureString $password -AsPlainText -Force
$global:Cred = New-Object System.Management.Automation.PSCredential($username, $Password)
Set-CdmCredential -Domain test.com -Credential $Cred
function CreateComputer-Group {
Param($Cred,$zone,$computerrole)
try {
New-ADGroup -Path "ou=Role Groups-Computer,ou=Centrify,ou=Operations,dc=qateradatacloud,dc=com" -Name $computerrole -GroupScope Global -GroupCategory Security -Credential $Cred -ErrorAction Stop
} catch {
$ErrorMessage = $_.Exception
return $ErrorMessage
break
}
}
function create-computerRole {
try {
$ADGroupName = Get-ADGroup -Identity $computerrole
Write-Host "********** Get Command Outout *********"
Write-Host $ADGroupName
Write-Host $CustomerZone
Write-Host $computerrole
$global:Hellow = New-CdmComputerRole -Zone $CustomerZone -Name $computerrole -Group $ADGroupName
Write-Host $Hellow
} catch {
$ErrorMessage = $_.Exception
return $ErrorMessage
}
}
Not sure why New-CdmComputerRole command showing no such object on server.
Here is the output:
********** Get Command Outout *********
CN=123413-NPARC,OU=Role Groups-Computer,OU=Centrify,OU=Operations,DC=qateradatacloud,DC=com
CN=AWS,CN=qateradatacloud,CN=Zones,OU=Centrify,OU=Operations,DC=qateradatacloud,DC=com
123413-NPARC
System.DirectoryServices.DirectoryServicesCOMException (0x80072030): There is no such object on the server.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.RefreshCache(String[] propertyNames)
at Centrify.DirectControl.Util.AD.DirectoryEntryEx.RefreshCache(DirectoryEntry de, String[] propertyNames)
at Centrify.DirectControl.Util.ActiveDirectory.Session.GetDirectoryEntryCheckOffline(String domainDcIpNetbios, String dn, String[] propertiesToLoad)
at Centrify.DirectControl.Util.ActiveDirectory.Session.GetDirectoryEntry(String domainDcIpNetbios, String dn, String[] propertiesToLoad)
at Centrify.DirectControl.Util.ActiveDirectory.Session.GetDirectoryEntry(String dn, String[] propertiesToLoad)
at Centrify.DirectControl.PowerShell.Types.CdmAdPrincipal.BindDirectoryEntry(Session session)
at Centrify.DirectControl.PowerShell.Types.CdmAdObject.Bind(Session session)
at Centrify.DirectControl.PowerShell.Commands.NewCdmComputerRole.InnerBeginProcessing()
at Centrify.DirectControl.PowerShell.CmdletBase.BeginProcessing()
at System.Management.Automation.Cmdlet.DoBeginProcessing()
at System.Management.Automation.CommandProcessorBase.DoBegin()

Finally I had split entire script into two scripts. One for Create AG-Group and another for all Centrify Commands

Related

How to pass variable value from a map defined outside invoke command and to be used after invoke command

I am writing a script in powershell where after login with User 1 on a system, it will switch to user 2 and then make a connection to database with this user. However, the dbinstance details, port No and Computer name to be passed in invoke command will be defined as a map before the 2nd invoke command i.e. when it will invoke the command to open powershell with 2nd user(db user). It is able to take userid in this case i.e. when to invoke the powershell connection with 2nd user, however it is not able to pass the values of dbinstance and port to next sqlcmd invoke. Below is the code for reference. In this code it works fine while getting $inputMap.UserNameP, however it fails in passing $inputMap.DBInstance,$inputMap.PortNo.
$UserName = 'User1'
$securekey = #'
securekey1
'# |ConvertTo-SecureString -AsPlainText -Force;
$concreds=New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $securekey;
Invoke-Command -Credential $concreds -ComputerName 'abc.domainname'-Authentication Credssp -ScriptBlock {
function checkFaultHighUtilization() {
$local:ExecStdOperatorOut=Invoke-Command -ScriptBlock {
$inputMap=#{"UserNameP"="User2";"DBInstance"="databaseinstancename";"PortNo"="portnumber";};
$securekey1 = "securekey1"
$finalresult = #()
$securekey2 = $securekey1 | ConvertTo-SecureString -AsPlainText -Force;
$concreds=New-Object System.Management.Automation.PSCredential -ArgumentList $inputMap.UserNameP, $securekey2;
Invoke-Command -Credential $concreds -ComputerName 'computername' -Authentication Credssp -ScriptBlock {
$var1=Invoke-Sqlcmd -query "
Begin
select * from db
End" -ServerInstance "$inputMap.DBInstance,$inputMap.PortNo"
##if (($var1.count) -gt 0) {
foreach($row in $var1){
$finalresult+=$row.a+':'+$row.b+':'+$row.c
echo $finalresult
}
}
}
$local:ExecStdOperatorRet=if($local:ExecStdOperatorOut) {0} else {1}
return $local:ExecStdOperatorRet,$local:ExecStdOperatorOut;
};
$ESExecReturn,$ESExecOutput=checkFaultHighUtilization
$ESExecOutput=($ESExecOutput | Out-String).Trim();
Write-output "ESExecOutput:";
Write-output $ESExecOutput;
Write-output ":ESExecOutput";Write-output $("ESExecError:" + $Error + ":ESExecError");
Write-output $("ESExecReturn:" + $ESExecReturn + ":ESExecReturn");
}
$scriptBlockOne = {
$variableA = "Hello World"
return $variableA
}
$scriptBlockTwo = {
param (
$inputString
)
Write-host $inputString
}
$invokeCommandReturn = Invoke-Command -ScriptBlock $scriptBlockOne
Invoke-Command -ScriptBlock $scriptBlockTwo -ArgumentList $invokeCommandReturn
You're trying to use expressions such as $inputMap.DBInstance as-is inside an expandable string ("..."), which is syntactically not supported.
To use expressions, you must enclose them in $(...), the subexpression operator.
See this answer for a comprehensive discussion of string interpolation in PowerShell.
Therefore:
# ...
$var1 = Invoke-Sqlcmd -Query "
Begin
select * from db
End" -ServerInstance "$($inputMap.DBInstance),$($inputMap.PortNo)" # Note the $()
# ...

Add a computer to an AD group on a specific domain controller via ADSI adapter

I run this script in a user context that has privileges to add members to my AD group. I verified permissions already and I can add members manually via ADUC.
I'd like to add my machine to a specific group on a specific domain controller. I'm very unfamiliar with ADSI usage and I pieced together the below script based on other examples. I'm unable to use PS AD module at the time this script will be ran.
Param(
[Parameter(Mandatory)]
[string]$GroupName
)
#Find domain controllers
$searcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://OU=Domain Controllers,DC=corp,DC=thing,DC=com")
$searcher.Filter = "(objectclass=computer)"
$DomainControllers = $searcher.FindAll()
Write-Verbose "Found DCs:"
foreach ($dc in $DomainControllers.Properties.cn)
{
Write-Verbose "$dc"
}
$TargetController = $null
$ComputerDn = $null
foreach ($dc in $DomainControllers.Properties.cn)
{
$searcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://$dc/DC=corp,DC=thing,DC=com")
$searcher.Filter = "(&(objectclass=computer)(cn=$env:COMPUTERNAME))"
$result = $searcher.FindOne()
try {
if ($result)
{
$TargetController = $dc
Write-Verbose "Target controller set: $TargetController"
$ComputerDn = $result.Properties.distinguishedname
Write-Verbose "Computer DN: $ComputerDn"
break
}
else
{
Write-Verbose "Did not find $env:COMPUTERNAME on $dc"
}
}
catch
{
Write-Verbose "$dc ERROR"
}
}
if ($TargetController)
{
$GroupSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://$TargetController/DC=corp,DC=thing,DC=com")
$GroupSearcher.Filter = "(&(objectclass=group)(cn=$GroupName))"
$GroupDn = $GroupSearcher.FindOne().Properties.distinguishedname
$Group = [ADSI] "LDAP://$TargetController/$GroupDn"
$ComputerSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://$TargetController/DC=corp,DC=thing,DC=com")
$ComputerSearcher.Filter = "(&(objectclass=computer)(cn=$env:COMPUTERNAME))"
$result = $ComputerSearcher.FindOne().Properties.memberof -match "cn=$GroupName,"
if (!$result)
{
try
{
$Computer = [adsi] "LDAP://$TargetController/$ComputerDn"
$Group.Add("$Computer")
}
catch
{
$_.Exception.Message ; Exit 1
}
}
else
{
Write-Verbose "$env:COMPUTERNAME already a member of $GroupName"
}
}
Running this I get the error "Exception calling "Add" with "1" argument(s): "Exception from HRESULT: 0x80005000". I'm open to any alternatives!
As Bill Stewart commented you should either remove the [adsi] accelerator
$Computer = "LDAP://$TargetController/$ComputerDn"
$Group.Add($Computer)
or specify the path
$Computer = [adsi] "LDAP://$TargetController/$ComputerDn"
$Group.Add($Computer.path)
The method expects the path which you've already constructed with "LDAP://$TargetController/$ComputerDn" which makes the cast to an adsi object unnecessary.

PowerShell OpenLDAP query returns nothing

I'm trying to retrieve OpenLDAP 2.4 users info.
Connection and bind are OK but request return nothing.
After some investigations, I discovered that there are more than 150 000 records to import. I tried to change $ModelQuery size limit but it didn't change a thing.
What would be the good way to manage this?
$HostName = "ldap.domain.com:389"
$user = 'user'
$Password = ConvertTo-SecureString 'password' -AsPlainText -Force
$pass = [PSCredential]::($user, $Password)
$null = [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")
$LDAPConnect = New-Object System.DirectoryServices.Protocols.LdapConnection "$HostName"
$LDAPConnect.AuthType = [System.DirectoryServices.Protocols.AuthType]::Basic
$LDAPConnect.SessionOptions.ProtocolVersion = 3
try {
$ErrorActionPreference = 'Stop'
$LDAPConnect.Credential = [PSCredential]::($user, $Password)
$ErrorActionPreference = 'Continue'
} catch {
throw "Erreur Bind LDAP - $($_.Exception.Message)"
}
Write-Verbose "Bind LDAP réussi" -Verbose
$BaseDn = 'ou=accounts,dc=domain,dc=com'
$Scope = [System.DirectoryServices.Protocols.SearchScope]::Subtree
$AttrList = $null
$Filter = '(property=staff)'
$ModelQuery = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $BaseDn, $Filter, $Scope, $AttrList
$ModelQuery.SizeLimit = 10
try {
$ErrorActionPreference = 'Stop'
$ModelRequest = $LDAPConnect.SendRequest($ModelQuery)
$ModelRequest.
$ErrorActionPreference = 'Continue'
} catch {
throw "Probleme de recherche sélection - $($_.Exception.Message)"
}
$ModelRequest.Entries | Export-Csv c:\res.csv
just add variable#() and put entries in it then pipe in csv

Moving computer to another OU in OSD with PowerShell

I am having a lot of trouble getting this code to work in a TS environment.
From a Windows environment, it works great. Just about any variation you will find with a google search of this code works fine in Windows. However in a Task Sequence these variations just produce different error messages for why the computer can't be moved.
Unspecified Error
The specified domain either doesn't exist or couldn't be contacted
Instance of an object not set to an object
I feel that something is happening when we get to the psbase.MoveTo() method call. Up to that point, it can print something out that looks like a reasonable object. In other words, they aren't null or something.
Then psbase.MoveTo() says no.
Example code.
$logFile = "MoveComputerLog.txt"
# Domain Credentials
$account = "domain\osdaccount"
$password = "thepassword"
function logMessage {
param ([string]$logstring)
Write-Host $logstring
Add-content $logFile -value $logstring
}
$computerName = "COMPUTERNAME"
logMessage "computerName: $computerName"
$root = "LDAP://sweet.domain.com"
$domain = New-Object System.DirectoryServices.DirectoryEntry($root, $account, $password)
$search = New-Object System.DirectoryServices.DirectorySearcher($domain)
$search.filter = "(&(objectClass=computer)(name=$computerName))"
$result = $search.findall()
$computerDN = $result.Properties.Item("DistinguishedName")
logMessage "DN: $computerDn"
$computer = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$computerDN", $account, $password)
logMessage "Computer: $computer"
$destination = "LDAP://ou=here,ou=goes,ou=it,dc=sweet,dc=domain,dc=com"
$ou = New-Object System.DirectoryServices.DirectoryEntry($destination, $account, $password)
try {
# "The specified domain couldn't be connected or doesn't exist."
$computer.psbase.MoveTo($ou.Path)
} catch {
Write-Host "Encountered error while moving $computerName"
logMessage $error[0]
}
Here is the definition, ADSI is important:
PS C:\> $computer.psbase.MoveTo
OverloadDefinitions
-------------------
void MoveTo(adsi newParent)
void MoveTo(adsi newParent, string newName)
You can try this, rigth after $result = $search.findall() :
$computer = [ADSI]$result.path
$computer.psbase.Moveto( [ADSI]LDAP://ou=here,ou=goes,ou=it,dc=sweet,dc=domain,dc=com )

Having Trouble Passing Vars between forms

im working in powershell studio
im trying to pass a string from mainform to secondform
and the var stays empty
[MainForm]
Param (
[Parameter(Mandatory=$false)]
[String]$computer,
[String]$UserName
)
$OnLoadFormEvent={
#TODO: Initialize Form Controls here
# try{
# Import-Module ActiveDirectory
# }
# catch{
# $ErrorMessage = $_.Exception.Message
# [System.Windows.Forms.MessageBox]::Show($ErrorMessage)
# }
}
#
##region Control Helper Functions
#
#endregion
$buttonOK_Click={
#TODO: Place custom script here
if ($checkboxComputer.Checked) {
$computer = $textboxinput.Text
Call-Computer_Form_pff
}
if ($checkboxUser.Checked){
$UserName = $textboxinput.Text
Call-User_Form_pff
}
else{
$ErrorMessage = "You Must Select At Least One Checkbox"
[System.Windows.Forms.MessageBox]::Show($ErrorMessage)
}
}
[SecondForm]
$FormEvent_Load={
#TODO: Initialize Form Controls here
try {
Call-MainForm_pff -computer $Computer
$computerSystem = get-wmiobject Win32_ComputerSystem -ComputerName $Computer
}
catch{
$ErrorMessage = $_.Exception.Message
Write-Host $ErrorMessage
# #[System.Windows.Forms.MessageBox]::Show($ErrorMessage)
}
}
from what i read it should work when i put in on the mainform's param section and call it this way from secondform:
Call-MainForm_pff -computer $Computer
can anyone help me with this?