Simple PowerShell script to create a computer group in AD. If the group exists, print already exists else create new. But something is wrong and its not creating a new group.
Import-Module ActiveDirectory
Import-Module Centrify.DirectControl.PowerShell
Clear-Variable -Name "Result"
Clear-Variable -Name "JSONOutput"
Clear-Variable -Name "ErrorMessage"
Clear-History
$username='<>';
$password='<>';
$computerGroup = 'Sample-New-Role';
# ************* SET CREDENTIALS *************************************
$Password = ConvertTo-SecureString $password -AsPlainText -Force
$global:Cred = New-Object System.Management.Automation.PSCredential($username,$Password)
Set-CdmCredential -Domain (Get-WmiObject Win32_ComputerSystem).Domain -Credential $Cred
$global:DomainController = Get-ADDomain -Current LocalComputer
Set-CdmPreferredServer -Domain (Get-WmiObject Win32_ComputerSystem).Domain -Server $global:DomainController.InfrastructureMaster
$global:OUPath = Get-ADOrganizationalUnit -Filter 'Name -like "Role Groups-Computer"'
# ************************ Create Zone ******************************
try{
if(Get-ADGroup -filter {Name -eq $computerGroup} -ErrorAction Continue)
{
$Result = "Already_Exists"
} else
{
New-ADGroup -Name $computerGroup -GroupScope Global -GroupCategory Security -Path $global:OUPath -Credential $Cred
$Result = 'Success'
}
}
catch{
$ErrorMessage = $_.Exception
}
# ************************* Result *********************************
$JSONOutput = #{"result"=$Result;"error"=$ErrorMessage} | ConvertTo-Json -Compress
Write-Output $JSONOutput
Output: If Group already exist then just create new else print 'Already_Exists'
It works fine if group already exists but failed and error out when new group. Instead of an error, it should create the group. Anything wrong with the condition?
{"error":{"Message":"Cannot find an object with identity: \u002709328-Sample-New-Role\u0027 ....
Import-Module ActiveDirectory
Import-Module Centrify.DirectControl.PowerShell
Clear-Variable -Name "Result"
Clear-Variable -Name "JSONOutput"
Clear-Variable -Name "ErrorMessage"
Clear-History
$username='<>';
$password='<>';
$computerGroup = 'Sample-New-Role';
# ************* SET CREDENTIALS *************************************
$Password = ConvertTo-SecureString $password -AsPlainText -Force
$global:Cred = New-Object System.Management.Automation.PSCredential($username,$Password)
Set-CdmCredential -Domain (Get-WmiObject Win32_ComputerSystem).Domain -Credential $Cred
$global:DomainController = Get-ADDomain -Current LocalComputer
Set-CdmPreferredServer -Domain (Get-WmiObject Win32_ComputerSystem).Domain -Server $global:DomainController.InfrastructureMaster
$global:OUPath = Get-ADOrganizationalUnit -Filter 'Name -like "Role Groups-Computer"'
# ************************ Create Zone ******************************
try{
if(Get-ADGroup -filter {Name -eq $computerGroup} -ErrorAction Continue)
{
$Result = "Already_Exists"
} else
{
New-ADGroup -Name $computerGroup -GroupScope Global -GroupCategory Security -Path $global:OUPath -Credential $Cred
$Result = 'Success'
}
}
catch{
$ErrorMessage = $_.Exception
}
# ************************* Result *********************************
$JSONOutput = #{"result"=$Result;"error"=$ErrorMessage} | ConvertTo-Json -Compress
Write-Output $JSONOutput
Related
I use this script for check on multiple machine if I have installed some apps and now the script return in txt file result. (format hostname\nYes/No). How can I change return result in csv file in 2 columns ; 1.Hostname ; 2. Result ?
actual result.txt
hostname
YES / NO
desired csv export
Hostname | Result
hostname | YES / NO / OFFLINE
script
$Computers = Get-Content -Path C:\Users\m\Desktop\ip.txt | Where-Object { $_ -match '\S' }
foreach($Computer in $Computers){
Write-Host $Computer
$User = "ussr"
$Password = "pssd"
$Command = 'hostname && if exist "C:\LdApp.exe" (echo YES) else (echo NO)'
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
Get-SSHTrustedHost | Remove-SSHTrustedHost
try{
$SessionID = New-SSHSession -ComputerName $Computer -Credential $Credentials -AcceptKey:$true
Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command | Select -Expand Output | Add-Content -Path result.txt}
catch {Add-Content -Path result.txt -Value "$Computer conectare esuata!"}
}
Thank you,
I have modified your code and not tested it. I will do some thing like this
$result = Get-Content -Path C:\Users\m\Desktop\ip.txt | ForEach-Object {
$computer = $_
try {
Write-Host $Computer
$User = "ussr"
$Password = "pssd"
$Command = 'if exist "C:\LdApp.exe" (echo YES) else (echo NO)'
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
Get-SSHTrustedHost | Remove-SSHTrustedHost
$SessionID = New-SSHSession -ComputerName $Computer -Credential $Credentials -AcceptKey:$true
$output = if ($SessionID) {
(Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command).Output
}
else {
"Offline"
}
}
catch {
{
Write-Host "$Computer conectare esuata!"
$output = "conectare esuata!"
}
}
[PsCustomObject]#{
'Hostname' = $computer
'Status' = $output
}
}
$result | Export-csv -Path "C:\Users\m\Desktop\result.csv" -NoTypeInformation
Answer2: for multiple commands and capturing results, and yet again not tested :(
Get-Content -Path C:\Users\m\Desktop\ip.txt | ForEach-Object {
$computer = $_
try {
Write-Host $Computer
$User = "ussr"
$Password = "pssd"
$Command = 'hostname && if exist "C:\LdApp.exe" (echo YES) else (echo NO)'
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
Get-SSHTrustedHost | Remove-SSHTrustedHost
$SessionID = New-SSHSession -ComputerName $Computer -Credential $Credentials -AcceptKey:$true
if ($SessionID) {
$Output = (Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command).Output
$result = $Output.split("`n")
[PSCustomObject]#{
"HostName" = $result[0]
"IPAddress" = $result[1] # Print $result to verify the exact index of this value.
"Status" = $result[2]
}
}
else {
[PSCustomObject]#{
"HostName" = $computer
"IPAddress" = "NA"
"Status" = "offline"
}
}
}
catch {
{
Write-Host "$Computer conectare esuata!"
}
}
} | Export-csv -Path "C:\Users\m\Desktop\result.csv" -NoTypeInformation
I use this script for check file size. How can I make to verify each computers ip's in ip.txt and the result print in results.txt ?
Thank you!
$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
Start-Transcript -path C:\Users\user\Desktop\Check_File.txt -append
$Computers = Get-Content -Path C:\Users\user\Desktop\ip.txt
foreach($Computer in $Computers){
$User = "admin"
$Password = "paSSw"
$Command = "dir C:\Proset\SRM\abc.ddc && hostname"
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
Get-SSHTrustedHost | Remove-SSHTrustedHost
$SessionID = New-SSHSession -ComputerName $Computer -Credential $Credentials -AcceptKey:$true
Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command | Select -Expand Output > result.txt
}
My workflow:
check if server is pingable
find if they are domain connected or not and perform a task accordingly. if Operating system 2012 and/or R2 ,2016 or 2019 newer OSes then I will run Get-SmbServerConfiguration cmdlet. if machine is not a part of default domain then else block will run.
if Operating system 2003 or 2008 oldest OSes then I will run Get-Wmi cmdlet. if machine is not a part of default domain then else block will run.
Finally , I will concentanate $results variable.
My question is :
1- How can we get remotely regedit value for 2003 or 2008 oldest OSes IS NOT a part of default domain insie else block?
Also , Condition will be like below.
if SMB1 value is "0" then result will be `false`
if SMB1 value is "1" then result will be `true`
if SMB1 value is not exist then result will be `not exist value`
2- How can I create object properties $SMBAudit variable ? because , I will concentanate all outputs inside $results variable.
$reg = [wmiclass]"\\$computer\root\default:StdRegProv"
$SMBAudit = $reg.GetStringValue($basekey, $subkey, $value).sValue
My desired output :
Computername,SMB1Enabled
Host01,True
Host02,False
I will write so far a script like below. but I am stucking somethings.
Script :
# Computer List
$allComputers = Get-Content .\path\to\computers.txt
read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring_domain.txt
read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring_local.txt
# Create empty array of results
$Results = #()
# Loop through computers
foreach($computer in $allComputers) {
# check if server is pingable before running the query on the server
if (Test-Connection $computer -Count 1 -Quiet) {
Write-Host "`n`n$computer is online!" -BackgroundColor Green -ForegroundColor Black
}
if(Get-ADComputer -Filter {Name -eq $computer -and OperatingSystem -notlike '*Windows*Server*2003*' -and OperatingSystem -notlike '*Windows*Server*2008*'})
{
#"machine $_ is a part of default domain"
# The command we want to run
$username = "domain01\admin01"
$password = Get-Content 'C:\mysecurestring_domain.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {Get-SmbServerConfiguration | Select EnableSMB1Protocol }
# Create properties
$Properties = #{
# Populate the properties "Computername" and "SMB1Enabled" with variables
Computername = $Computer
SMB1Enabled = $SMB.EnableSMB1Protocol
}
# Add the properties to the result for each object
$Results += New-Object psobject -Property $Properties
}
else
{
#"machine $_ IS NOT a part of default domain"
$username = "localadmin01"
$password = Get-Content 'C:\mysecurestring_local.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {Get-SmbServerConfiguration | Select EnableSMB1Protocol }
# Create properties
$Properties = #{
# Populate the properties "Computername" and "SMB1Enabled" with variables
Computername = $Computer
SMB1Enabled = $SMB.EnableSMB1Protocol
}
# Add the properties to the result for each object
$Results += New-Object psobject -Property $Properties
}
# Oldest OSes
if(Get-ADComputer -Filter {Name -eq $computer -and OperatingSystem -notlike '*Windows*Server*2012*' -and OperatingSystem -notlike '*Windows*Server*2016*' -and OperatingSystem -notlike '*Windows*Server*2019*'})
{
#"machine $_ is a part of default domain"
# The command we want to run
<# HKEY_CLASSES_ROOT (2147483648 (0x80000000))
HKEY_CURRENT_USER (2147483649 (0x80000001))
HKEY_LOCAL_MACHINE (2147483650 (0x80000002))
HKEY_USERS (2147483651 (0x80000003))
HKEY_CURRENT_CONFIG (2147483653 (0x80000005))
#>
$basekey = [uint32]'0x80000002'
$subkey = 'SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters'
$value = 'SMB1'
$reg = [wmiclass]"\\$computer\root\default:StdRegProv"
$SMBAudit = $reg.GetStringValue($basekey, $subkey, $value).sValue
}
else
{
#"machine $_ IS NOT a part of default domain"
}
# Output
$Results | Select-Object Computername, SMB1Enabled | Out-File -Filepath c:\temp\smb1-computers.txt
I think you are over complicating this and although not tested by me, you could try this:
# Computer List
$allComputers = Get-Content '.\path\to\computers.txt'
# get credentials for domain-joined machines and for local machines
$domainCred = Get-Credential -UserName "domain01\admin01" -Message "Please enter the DOMAIN password"
$localCred = Get-Credential -UserName "localadmin01" -Message "Please enter the LOCAL password"
# loop through the list of computers and collect output in variable $Results
$Results = foreach($computer in $allComputers) {
# check if server is pingable before running the query on the server
if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
Write-Host "$computer is online!" -BackgroundColor Green -ForegroundColor Black
$server = Get-ADComputer -Filter "Name -eq '$computer'" -Properties OperatingSystem -ErrorAction SilentlyContinue
# if domain joined, use $domainCred, otherwise $localCred
if ($server) {
$cred = $domainCred
$version = ([regex]'Windows Server (\d+)').Match($server.OperatingSystem).Groups[1].Value
}
else {
$cred = $localCred
$info = Get-WmiObject -ComputerName $computer -Credential $cred -Class Win32_OperatingSystem
$version = ([regex]'Windows Server (\d+)').Match($info.Caption).Groups[1].Value
}
if ($version -eq '2003') {
# try reading the registry
try {
$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$RegKey = $RegBase.OpenSubKey("SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")
$SMB = $RegKey.GetValue("SMB1")
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = ($null -eq $SMB -or [int]$SMB -eq 1) }
}
catch {
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = 'Could not read Remote Registry' }
}
finally {
if ($RegBase) { $RegBase.Close() }
if ($RegKey) { $RegKey.Close() }
}
}
elseif ($version -eq '2008') {
# Older OS
try {
# try via WinRM
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' -Name SMB1
} -ErrorAction Stop
# output an object
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = ($null -eq $SMB -or [int]$SMB -eq 1) }
}
catch {
# try reading the registry
try {
$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$RegKey = $RegBase.OpenSubKey("SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")
$SMB = $RegKey.GetValue("SMB1")
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = ($null -eq $SMB -or [int]$SMB -eq 1) }
}
catch {
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = 'Could not read Remote Registry' }
}
finally {
if ($RegBase) { $RegBase.Close() }
if ($RegKey) { $RegKey.Close() }
}
}
}
else {
# Newer OS
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock { Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol }
# output an object
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = $SMB.EnableSMB1Protocol }
}
}
else {
Write-Warning "Computer $computer is off-line"
# output an object anyway, so that in the CSV it is known that the computer didn't ping
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = 'Off-Line' }
}
}
# Output on screen
$Results | Format-Table -AutoSize
# Output to CSV file
$Results | Export-Csv -Path 'c:\temp\smb1-computers.csv' -NoTypeInformation -UseCulture
I have a PowerShell script I am writing to create new users in our domain, as well as email address. The script works when I run it directly on Exchange. However, if I try to do it from my local PC either with Enter-PSSession or Invoke-Command I get the error:
The term 'Get-ADUser' is not recognized as the name of a cmdlet...
Running that same command from the local machine does work. And running that command on the remote machine works, just not if I run the script remotely.
Here is my script:
$cred = Get-Credential
$first_name = Read-Host -Prompt "What is the new user's first name?"
$last_name = Read-Host -Prompt "What is the new user's last name?"
$copy_from = Read-Host -Prompt "Copy from other user (leave blank if not)?"
$password = Read-Host -Prompt "New user's password?"
$ss_password = ConvertTo-SecureString -String $password -AsPlainText -Force
$new_user_name = $last_name.Substring(0,3) + $first_name.Substring(0,2)
$new_user_name = $new_user_name.ToLower()
Write-Host "Creating user $new_user_name..." -ForegroundColor Green
if ([string]::IsNullOrEmpty($copy_from))
{
Write-Host "Setting up new user (not copying...)" -ForegroundColor Yellow
New-ADUser -Name "$first_name $last_name" -AccountPassword $ss_password -SamAccountName $new_user_name -PassThru | Enable-ADAccount
}
else
{
$copy_from_user = Get-ADUser -Identity $copy_from
Write-Host "Copying user from: " $copy_from_user.Name -ForegroundColor Yellow
$ou = $copy_from_user.DistinguishedName -replace '^cn=.+?(?<!\\),'
New-ADUser -Name "$first_name $last_name" -AccountPassword $ss_password -Path $ou -SamAccountName $new_user_name -PassThru | Enable-ADAccount
$new_user = Get-ADUser -Identity $new_user_name
#Time to copy their group memberships
Get-ADUser -Identity $copy_from -Properties memberof | Select-Object -ExpandProperty memberof | Add-ADGroupMember -Members $new_user_name
}
$pn = $new_user_name + "#INDY"
Set-ADUser -Identity $new_user_name -GivenName $first_name -Surname $last_name -UserPrincipalName $pn
#Now create email
$email_select = Read-Host -Prompt "Select email domain (1. Woodmizer; 2. Lastec; 3. Brightstone)"
if ($email_select -eq 2)
{
$domain = "#lastec.com"
}
elseif ($email_select -eq 3)
{
$domain = "#brightstoneabrasives.com"
}
else
{
$domain = "#woodmizer.com"
}
$email_address1 = $first_name.Substring(0,1) + $last_name + $domain
Write-Host "Creating mailbox $email_address1..." -ForegroundColor Green
Enable-Mailbox -Identity $new_user_name -Database "Mailbox Database 1188513962"
Start-Sleep -s 10
Get-Mailbox -Identity $new_user_name | Set-Mailbox -EmailAddresses #{add="$email_address1"} -EMailAddressPolicyEnabled $false
Get-Mailbox -Identity $new_user_name | Set-Mailbox -PrimarySmtpAddress $email_address1 -EmailAddressPolicyEnabled $false
Write-Host "Finished." -ForegroundColor Green
If you want this script to run on machines that don't have the Active Directory module, you can simply add this to the top of your script to import the cmdlets via session..
$cred = Get-Credential "DOMAIN\adminuser"
$ADsession = New-PSSession -ComputerName DOMAINCONTROLLERNAME -Credential $cred
Import-Module -PSSession $ADsession ActiveDirectory
I also notice you're trying to run Exchange cmdlets..
$exchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://EXCHANGESERVER/PowerShell/" -Authentication Kerberos
Import-PSSession $exchSession
It looks like the ActiveDirectory module is not installed on that machine, you can install the MSFT RSAT tools to get it.
Try the following, It works!! {I tried after giving the Authentication type}
$pass = ConvertTo-SecureString -AsPlainText 'PASSWORD' -Force
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'USERNAME',$pass
$s=New-PSSession SERVERNAME -Credential $MySecureCreds -Authentication Credssp
Invoke-Command -Session $s -scriptblock {
Get-CsUser User
}
The function Get-loggedOnUser shows 3 items, and the code can be found here LoggedInUser
Computer Name
Logged on user
Sid of the user
I would like to be able to take the results of the LoggedOnUser function (only need the logged in user) and pipe the results to the variable below called Username.
Import-Module ActiveDirectory
function Get-LoggedOnUser
$credential = Get-Credential
$computers = "MachineName"
foreach ($machine in $computers)
{
Get-LoggedOnUser -ComputerName $machine
$username = $_.LoggedOn
$sid = ((get-aduser $username).SID).Value
Invoke-Command -ComputerName $machine -Credential $credential -ScriptBlock { New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS; New-ItemProperty -Path "HKU:\$($args[0])\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -PropertyType String -Name AutoConfigURL -Value "http://proxy.domain.com/proxies/proxy.pac" -Force } -argumentlist $sid
}
$loggedOn=Get-LoggedOnUser -computername $machine
$username = $loggedOn.LoggedOn
$sid = $loggedOn.Sid #as this is already returned from above funtion
$sid = ((get-aduser $username).sid).value #if you want to still get it from AD