Create Active Directory users with certain attributes in a script - if-statement

I'm working on a PowerShell script to make it easier to create Active Directory users including some attributes. For now I need to process the "Manager" field. We have 4 departments, 4 managers. I want to create this using logic like "if department is 1 of the 4 departments then give 1 of the 4 managers."
How can I process this?
Import-Module activedirectory
#Store the data from ADUsers.csv in the $ADUsers variable
$ADUsers = Import-csv "c:\temp\scripts\ADUsers.csv"
#Loop through each row containing user details in the CSV file
foreach ($User in $ADUsers)
{
#Read user data from each field in each row and assign the data to a variable as below
$Firstname = $User.firstname
$Lastname = $User.lastname
$Username = $User.username
$Password = $User.password
$OU = $User.ou #This field refers to the OU the user account is to be created in
$userprincipalname = $user.userprincipalname
$displayname = $user.displayname
$title = $user.jobtitle
$department = $user.department
#Check to see if the user already exists in AD
if (Get-ADUser -F {SamAccountName -eq $Username})
{
#If user does exist, give a warning
Write-Warning "A user account with username $Username already exist in Active Directory."
}
else
{
Write-host
#User does not exist then proceed to create the new user account
#Account will be created in the OU provided by the $OU variable read from the CSV file
New-ADUser -Name $displayname -SamAccountName $Username -UserPrincipalName $userprincipalname -GivenName $Firstname -Surname $Lastname -Enabled $True -DisplayName $displayname -AccountPassword (convertto-securestring $Password -AsPlainText -Force)
}
} #end function

Something like this?
if ($department -eq "A")
{
$manager = "ManagerA"
}
else if ($department -eq "B")
{
$manager = "ManagerB"
}
else if ($department -eq "C")
{
$manager = "ManagerC"
}
else if ($department -eq "D")
{
$manager = "ManagerD"
}
New-ADUser -Name $displayname -SamAccountName $Username -UserPrincipalName $userprincipalname -GivenName $Firstname -Surname $Lastname -Enabled $True -DisplayName $displayname -AccountPassword (convertto-securestring $Password -AsPlainText -Force) -Manager $manager
"ManagerA/B/C/D" are SAM account name of user objects of managers.

I have solved the problem with a Switch like below.
Switch ($department) {
"dept 1" {$manager = "cn=jim smith,ou=west,dc=domain,dc=com"}
"dept 2" {$manager = "cn=sally wilson,ou=east,dc=domain,dc=com"}
"dept 3" {$manager = "cn=frank johnson,ou=east,dc=domain,dc=com"}
"dept 4" {$manager = "cn=mary tutle,ou=west,dc=domain,dc=com"}

Related

If no OU path entered set default instead

New to PS and need some help with $null values, I want to ask the user to set a OU path but if the user enters nothing then it will revert to the default which is in the if statement.
$OU = Read-Host -Prompt "Enter the new users OU path"
if($null -eq $OU)
{
$OU="CN=Users,DC=de,DC=ing,DC=kus,DC=tb"
}
else
{
}
Replaced the $null with "" as I was detecting a string.
$OU = Read-Host "Enter the new users OU path"
if ($OU -eq "")
{
$OU = "CN=Users,DC=**,DC=***,DC=***,DC=**"
}
else
{
}

Not taking the Else-if input powershell with Switch statement

I need help with PowerShell code. I have to update a couple of programs using PowerShell, but I am getting errors while running the script.
Inputs to the code are 1 and 0 for Switch condition and other inputs are foo, boo, Oracle to be updated, based on condition software will be updated.
$param = Read-Host -Prompt "Enter the input 1 or 0"
[bool]$upg = $true
$sftp = Read-Host "Please Enter the softwre to update"
switch ($param)
{
0{
Write-Output "Today is monday"
}
1
{
$prm_prd = Read-Host -Prompt "Are you going for operation upgrade"
if ($prm_prd -eq $upg)
{
Write-Output "System upgrade"
if ($sftp -eq 'foo')
{
Write-Output "foo upgrade"
}
elseif ( $sftp -eq 'boo')
{
Write-output "boo upgrade"
}
elseif ( $sftp -eq 'Oracle')
{
Write-output "oracle upgrade"
}
}
}
}
Didn't you post some form of this before? Elseif not else-if.

Is there a way to create a Hyper-V checkpoint with a specified name through WMI?

I'm trying to find a way to create a Hyper-V checkpoint with a specified name through WMI. I am aware that it is possible to create a snapshot, and then rename it, as seen in this older question, but ideally I would like to create the checkpoint with the name I want to begin with.
This is for Hyper-V for Windows Server 2016. I have already tried setting ElementName to the name I want in the Msvm_VirtualSystemSnapshotSettingData object passed to the CreateSnapshot method, but this doesn't appear to work.
Same problem on my side. I used Msvm_VirtualSystemSnapshotSettingData to set ElementName but it do not set name. Maybe there is some method to rename.
I used this code of PowerShell to create snapshot with name:
$vm = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Query "select * from msvm_computersystem where elementname='$VMName'"
if($vm -eq $null){
throw "Failed to get VM with display name '$VMName'"
}
$cms = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_CollectionManagementService
if($cms -eq $null){
throw "Failed to get instance Msvm_CollectionManagementService"
}
[System.Management.ManagementBaseObject]$result = $cms.DefineCollection($snapshotname, $null, 0)
[int]$res = Job-Observation -WMIJobResult $result -JobAction "Define collection" -JobProgressCaption "Define collection"
if($res -eq 0)
{
$coll = [wmi]$result.DefinedCollection
$coll.Description = $SnapshotDescription
$result = $cms.AddMember($vm, $coll)
$res = Job-Observation -WMIJobResult $result -JobAction "Add collection as member" -JobProgressCaption "Add collection as member"
if($res -eq 0)
{
$csss = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_CollectionSnapshotService
$result = $csss.CreateSnapshot([string]$coll, $null, 32768, $null)
$res = Job-Observation -WMIJobResult $result -JobAction "Creating shapshot" -JobProgressCaption "Create snapshot"
$result = $cms.RenameCollection($snapshotname, [string]$coll)
$res = Job-Observation -WMIJobResult $result -JobAction "Set snaphost name" -JobProgressCaption "Set snapshot name"
}
}
It works fine from PowerShell. But it doesn't work from C++ code.
Got it working!! You can review my full PSscript: ScriptCode Take a look. You need to call ModifySystemSettings method to rename:
$vm = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Query "select * from msvm_computersystem where elementname='$VMName'"
if($vm -eq $null){
throw "Failed to get VM with display name '$VMName'"
}
$Msvm_VirtualSystemSnapshotService = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_VirtualSystemSnapshotService
if($Msvm_VirtualSystemSnapshotService -eq $null)
{
throw "Failed to get Msvm_VirtualSystemSnapshotService instance"
}
[WMI]$Msvm_VirtualSystemSnapshotSettingData = ([WMIClass]"\\.\root\virtualization\v2:Msvm_VirtualSystemSnapshotSettingData").CreateInstance()
if($Msvm_VirtualSystemSnapshotSettingData -eq $null)
{
throw "Failed to get Msvm_VirtualSystemSnapshotSettingData instance"
}
$Msvm_VirtualSystemSnapshotSettingData.ConsistencyLevel = 1
$Msvm_VirtualSystemSnapshotSettingData.IgnoreNonSnapshottableDisks = $true
$Msvm_VirtualSystemSnapshotSettingData.ElementName = $SnapshotName
$Msvm_VirtualSystemSnapshotSettingData.Description = $SnapshotDescription
$Msvm_VirtualSystemSnapshotSettingData
[System.Management.ManagementBaseObject]$result = $Msvm_VirtualSystemSnapshotService.CreateSnapshot(
$vm,
$Msvm_VirtualSystemSnapshotSettingData.GetText(2),
32768)
[int]$res = Job-Observation -WMIJobResult $result -JobAction "Creating snapshot" -JobProgressCaption "Create snapshot"
[WMI]$snapshot = (([WMI]$result.Job).GetRelated("Msvm_VirtualSystemSettingData") | % {$_})
$Msvm_VirtualSystemManagementService = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_VirtualSystemManagementService
if($Msvm_VirtualSystemManagementService -eq $null)
{
throw "Failed to get Msvm_VirtualSystemManagementService instance"
}
$snapshot.ElementName = $SnapshotName
$snapshot.Description = $SnapshotDescription
[System.Management.ManagementBaseObject]$result = $Msvm_VirtualSystemManagementService.ModifySystemSettings($snapshot.GetText(2))
[int]$res = Job-Observation -WMIJobResult $result -JobAction "Renaming snapshot" -JobProgressCaption "Rename snapshot"
$snapshot

powershell System.Collections.Generic.List[System.String] and foreach

I'm finding that I have the following Generic List, and I can see it has items in it, but when I try to run the code, it's not hitting inside the foreach. This is my code:
function SQLQueryWriteToFile([string]$SQLquery, [string]$extractFile)
{
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=blah;Database=blah;User ID=blah;Password=blah" #production #I have an error in this so it doesn't connect
$sqlConnection.Open()
if($sqlConnection.State -ne 'Open'){
$global:ErrorStrings.Add("Exception: $("Couldn't connect to DB with connection string given");; ") #this gets hit
}
###
$global:ErrorStrings = New-Object System.Collections.Generic.List[System.String] #System.Object]
$query = "Select blah"
$dir = "C:\blah"
SQLQueryWriteToFile $query $dir
$errorCodeAsString = ""
foreach ($item in $global:ErrorStrings.Members){
$errorCodeAsString += $item #this isn't hit
}
Any idea why it's not finding the error string in my list for the foreach loop, when I can see it's in there looking at $global:ErrorStrings? Based on this foreach list, I'm doing it correctly. I'm having trouble finding examples like what I'm doing. Thanks!
try this:
function SQLQueryWriteToFile([string]$SQLquery, [string]$extractFile)
{
[System.Data.SqlClient.SqlConnection] $sqlConnection=$null
[System.Data.SqlClient.SqlCommand] $command=$null
try
{
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=blah;Database=blah;User ID=blah;Password=blah"
$command = New-Object System.Data.SqlClient.SqlCommand
$command.Connection=$sqlConnection
$command.CommandText=$SQLquery
$sqlConnection.Open()
$command.ExecuteNonQuery()
}
catch
{
$global:ErrorStrings.Add($_.Exception.Message)
}
finally
{
if ($sqlConnection -ne $null)
{
$sqlConnection.Close()
$sqlConnection.Dispose()
}
if ($command -ne $null)
{
$command.Dispose()
}
}
}
$global:ErrorStrings = New-Object System.Collections.Generic.List[System.String]
$query = "Select blah"
$dir = "C:\blah"
$global:ErrorStrings.Clear()
SQLQueryWriteToFile $query $dir
$errorCodeAsString=""
for ($i = 0; $i -lt $global:ErrorStrings.Count; $i++)
{
$errorCodeAsString +=$global:ErrorStrings.Item($i)
}
$errorCodeAsString

PowerShell WebServiceProxy with forms authentication

I am working on building a few interfaces with Remedy 9.1 web services. It is configured with Forms authentication to get to the WSDL. I would like to keep it in that configuration so that the more powerful web services remain protected.
I have parts of a solution, but I am not sure that they can work together, perhaps you know of a solution?
This works if I remove forms auth:
function New-ObjectFromProxy {
param($proxy, $proxyAttributeName, $typeName)
# Locate the assembly for $proxy
$attribute = $proxy | gm | where { $_.Name -eq $proxyAttributeName }
$str = "`$assembly = [" + $attribute.TypeName + "].assembly"
invoke-expression $str
# Instantiate an AuthenticationHeaderValue object.
$type = $assembly.getTypes() | where { $_.Name -eq $typeName }
return $assembly.CreateInstance($type)
}
$Now = get-date -Format G
$Q = "'System Broadcast End Date' >= """ + $Now + """"
$proxy = New-WebServiceProxy -Uri "https://mycompany-itsm.columncloud.com/arsys/WSDL/public/servername/CFG%3ABroadcast"
$authHeader = New-ObjectFromProxy -proxy $proxy -proxyAttributeName "AuthenticationInfoValue" -typeName "AuthenticationInfo"
$authHeader.userName = "username"
$authHeader.password = "password"
$proxy.AuthenticationInfoValue = $authHeader
$Response = $proxy.GetList($Q,"","")
$Response | format-Table Broadcast_Start_Date, Broadcast_Message
However, if I move the webservice back behind the forms auth, I can get to the WSDL if I do this:
#this is the url that you want will send thae request to
$url = "https://mycompany-itsm.columncloud.com/arsys/servlet/LoginServlet"
#here you can set your POST params
$parameters = "username=username&pwd=ppaasswwoorrdd&encpwd=1&ipoverride=0&initialState=-1&timezone=-28800000&goto=/arsys/WSDL/protected/servername/HPD_IncidentInterface_Create_WS"
#creating the xmlHtpp system object
$http_request = New-Object -ComObject Msxml2.XMLHTTP
$http_request.open('POST', $url, $false)
#Setting required header of the request
$http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
$http_request.setRequestHeader("Content-length", $parameters.length)
#Assigning the params to the request
$Resp = $http_request.send($parameters)
echo $http_request.responseText
I would like to find a solution to combine these solutions together to use forms auth to get to the WSDL and create a webServiceProxy object. Perhaps my google-fu is weak, but I have not found a formsauth solution for new-webserviceProxy.
Origin code from POSHCODE site. updated to add formsauth
Basically I had to use the way back machine to figure out how this was done before it was made super simple by new-WebServiceProxy. I fire up a web request to post with forms auth data and grab the cookie for the conversation. If my cookie expires, I go get a new one (might explain my waistline).
Huge props to Oisin Grehan for publishing his code 7 years ago.
Call it like this:
.\New-WebServiceProxy-FormsAuth.ps1 -Url "https://mycompany/WSDL/public/servername/CFG%3ABroadcast" -Namespace "mystuff" -Cookies $CookieJar -lurl "https://mycompany/servlet/LoginServlet" -postData "username=username&pwd=ppaasswwoorrdd&encpwd=1&ipoverride=0&initialState=-1&timezone=-28800000"
# New-WebServiceProxy-FormsAuth.ps1 (v3.0 Sep 23, 2009)
#
# Oisin Grehan <oising#gmail.com> (x0n)
# ghangas
#
# Usage:
# $proxy = .\New-WebServiceProxy.ps1 [-Url] http://site/service.asmx -lurl <http://site/loginpostpage> -postData <form data url encoded> [[-SoapProtocol] <Soap | Soap12>] [-Namespace <namespace>] [-Cookies <CookieContainer>]
#
# to see available webmethods:
# $proxy | gm
#
param($url = $(throw "need `$url"), [string]$protocol = "Soap", [string]$Namespace="", [System.Net.CookieContainer]$CookieJar, [string]$lurl, [string]$postData)
[void][system.Reflection.Assembly]::LoadWithPartialName("system.web.services")
trap {
"Error:`n`n $error";
break;
}
#$request = [System.Net.WebRequest]::Create($url);
$dcp = new-object system.web.services.discovery.discoveryclientprotocol
if ($CookieJar -ne $null) {
If ($CookieJar.ToString() = "System.Net.CookieContainer") {
$dcp.CookieContainer = $CookieJar
}
}
Write-Progress "Discovery" "Searching..."
$dcp.AllowAutoRedirect = $true
try {[void]$dcp.DiscoverAny($url)
}
catch {
$CookieJar = New-Object System.Net.CookieContainer
$buffer = [text.encoding]::ascii.getbytes($postData)
[net.httpWebRequest] $req = [net.webRequest]::create($lurl)
$req.method = "POST"
$req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
$req.Headers.Add("Accept-Language: en-US")
$req.Headers.Add("Accept-Encoding: gzip,deflate")
$req.Headers.Add("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7")
$req.AllowAutoRedirect = $true
$req.UserAgent = "Mozilla/4.0"
$req.ContentType = "application/x-www-form-urlencoded"
$req.ContentLength = $buffer.length
$req.TimeOut = 50000
$req.KeepAlive = $true
$req.CookieContainer = $CookieJar
$reqst = $req.getRequestStream()
$reqst.write($buffer, 0, $buffer.length)
$reqst.flush()
$reqst.close()
[net.httpWebResponse] $res = $req.getResponse()
$dcp.CookieContainer = $CookieJar
[void]$dcp.DiscoverAny($url)
}
$dcp.ResolveAll()
# get service name
foreach ($entry in $dcp.Documents.GetEnumerator()) { # needed for Dictionary
if ($entry.Value -is [System.Web.Services.Description.ServiceDescription]) {
$script:serviceName = $entry.Value.Services[0].Name
Write-Verbose "Service: $serviceName"
}
}
Write-Progress "WS-I Basic Profile 1.1" "Validating..."
$ns = new-Object System.CodeDom.CodeNamespace $Namespace
$wref = new-object System.Web.Services.Description.WebReference $dcp.Documents, $ns
$wrefs = new-object system.web.services.description.webreferencecollection
[void]$wrefs.Add($wref)
$ccUnit = new-object System.CodeDom.CodeCompileUnit
[void]$ccUnit.Namespaces.Add($ns)
$violations = new-object system.web.Services.Description.BasicProfileViolationCollection
$wsi11 = [system.web.services.WsiProfiles]::BasicProfile1_1
if ([system.web.Services.Description.WebServicesInteroperability]::CheckConformance($wsi11, $wref, $violations)) {
Write-Progress "Proxy Generation" "Compiling..."
$webRefOpts = new-object System.Web.Services.Description.WebReferenceOptions
$webRefOpts.CodeGenerationOptions = "GenerateNewAsync","GenerateProperties" #,"GenerateOldAsync"
#StringCollection strings = ServiceDescriptionImporter.GenerateWebReferences(
# webReferences, codeProvider, codeCompileUnit, parameters.GetWebReferenceOptions());
$csprovider = new-object Microsoft.CSharp.CSharpCodeProvider
$warnings = [System.Web.Services.Description.ServiceDescriptionImporter]::GenerateWebReferences(
$wrefs, $csprovider, $ccunit, $webRefOpts)
if ($warnings.Count -eq 0) {
$param = new-object system.CodeDom.Compiler.CompilerParameters
[void]$param.ReferencedAssemblies.Add("System.Xml.dll")
[void]$param.ReferencedAssemblies.Add("System.Web.Services.dll")
$param.GenerateInMemory = $true;
#$param.TempFiles = (new-object System.CodeDom.Compiler.TempFileCollection "c:\temp", $true)
$param.GenerateExecutable = $false;
#$param.OutputAssembly = "$($ns.Name)_$($sdname).dll"
$param.TreatWarningsAsErrors = $false;
$param.WarningLevel = 4;
# do it
$compileResults = $csprovider.CompileAssemblyFromDom($param, $ccUnit);
if ($compileResults.Errors.Count -gt 0) {
Write-Progress "Proxy Generation" "Failed."
foreach ($output in $compileResults.Output) { write-host $output }
foreach ($err in $compileResults.Errors) { write-warning $err }
} else {
$assembly = $compileResults.CompiledAssembly
if ($assembly) {
if ($namespace) {
$serviceType = $assembly.GetType($namespace + "." + $serviceName)
} else {
$serviceType = $assembly.GetType($serviceName)
}
$assembly.GetTypes() | % { Write-Verbose $_.FullName }
} else {
Write-Warning "Failed: `$assembly is null"
return
}
# return proxy instance
$proxy = new-object $serviceType.FullName
$proxy # dump instance to pipeline
}
} else {
Write-Progress "Proxy Generation" "Failed."
Write-Warning $warnings
}
#Write-Progress -Completed
}