Powershell script to remove groups from users - powershell

I found this script to remove groups from a single user but i'm afraid to try it in my environment:
Question - is there a test lab online where i can run these scripts without breaking my own environment? Also can someone with more scripting/powershell knowledge verify that this is safe to run if i want to remove groups from a user? I was instructed to run the script with an argument after it i.e. c:/sripts/removegroups.ps1 username#domain" is that correct?
$user = $args[0] if (!$args[0]) {
} $mailbox=get-mailbox $user
$dgs= Get-DistributionGroup
foreach($dg in $dgs){
$DGMs = Get-DistributionGroupMember -identity $dg.Identity
foreach ($dgm in $DGMs){
if ($dgm.name -eq $mailbox.name){
write-host 'User Found In Group' $dg.identity
Remove-DistributionGroupMember $dg.Name -Member $user
}
}
}

You could use the whatif switch on the Remove-DistributionGroupMember command
$user = $args[0] if (!$args[0]) {
} $mailbox=get-mailbox $user
$dgs= Get-DistributionGroup
foreach($dg in $dgs){
$DGMs = Get-DistributionGroupMember -identity $dg.Identity
foreach ($dgm in $DGMs){
if ($dgm.name -eq $mailbox.name){
write-host 'User Found In Group' $dg.identity
Remove-DistributionGroupMember $dg.Name -Member $user -Whatif
}
}
}
The WhatIf switch instructs the command to simulate the actions that it would take on the object. By using the WhatIf switch, you can view what changes would occur without having to apply any of those changes. You don't have to specify a value with the WhatIf switch.
http://technet.microsoft.com/en-us/library/aa998016(v=exchg.150).aspx

Set $WhatIfPreference to $true, and all the commands in the script should display what would have happened had they been run for real. This is (slightly) easier than modifying the script commands one by one.

Would it look something like this?
$WhatIfPreference = $true
$user = $args[0] if (!$args[0]) {
} $mailbox=get-mailbox $user
$dgs= Get-DistributionGroup
foreach($dg in $dgs){
$DGMs = Get-DistributionGroupMember -identity $dg.Identity
foreach ($dgm in $DGMs){
if ($dgm.name -eq $mailbox.name){
write-host 'User Found In Group' $dg.identity
Remove-DistributionGroupMember $dg.Name -Member $user
}
}
}

PS C:\Windows\system32> $WhatIfPreference = $true
PS C:\Windows\system32> $user = $args[0] if (!$args[0]) {
At line:1 char:18
+ $user = $args[0] if (!$args[0]) {
+ ~~
Unexpected token 'if' in expression or statement.
At line:1 char:33
+ $user = $args[0] if (!$args[0]) {
+ ~
Missing closing '}' in statement block.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
ception
+ FullyQualifiedErrorId : UnexpectedToken
PS C:\Windows\system32>
PS C:\Windows\system32> } $mailbox=get-mailbox $user
At line:1 char:1
+ } $mailbox=get-mailbox $user
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
ception
+ FullyQualifiedErrorId : UnexpectedToken
PS C:\Windows\system32>
PS C:\Windows\system32> $dgs= Get-DistributionGroup
WARNING: By default, only the first 1000 items are returned. Use the ResultSize
parameter to specify the number of items returned. To return all items,
specify "-ResultSize Unlimited". Be aware that, depending on the actual number
of items, returning all items can take a long time and consume a large amount
of memory. Also, we don't recommend storing the results in a variable. Instead,
pipe the results to another task or script to perform batch changes.
PS C:\Windows\system32>
PS C:\Windows\system32> foreach($dg in $dgs){
>>enter code here
>> $DGMs = Get-DistributionGroupMember -identity $dg.Identity
>> foreach ($dgm in $DGMs){
>> if ($dgm.name -eq $mailbox.name){
>>
>> write-host 'User Found In Group' $dg.identity
>> Remove-DistributionGroupMember $dg.Name -Member $user

Related

If not run after get-service in powershell

I'm trying to access the service status of the remote server. i wrote this
$ServerList = get-content -Path "c:\users\cont015\Desktop\ServerList.txt"
ForEach ($ServerName in $ServerList)
{
$Status= Get-Service -ComputerName $ServerName | ?{$_.DisplayName -like "SQL Server (*"} | select Status | format-wide
if($st -eq "Running")
{
$SeverName
$Status
}
else
{
}
}
it is showing
$Status= Get-Service -ComputerName $ServerName | ?{$_.DisplayName -li ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Service], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand
in error. i don't know what i am missing. but when i run without if condition if shows proper output.
$ServerList = Get-Content -Path "c:\users\cont015\Desktop\ServerList.txt"
ForEach ($ServerName in $ServerList)
{
$Status= #(
Get-Service -ComputerName $ServerName -DisplayName "SQL Server (*" |
Select-Object -ExpandProperty Status)
if ("Running" -in $Status)
{
[PSCustomObject]#{
Server = $ServerName
Status = $Status
}
}
else
{
}
}
Explanation:
Get-Service docs: -DisplayName
Specifies, as a string array, the display names of services to be retrieved. Wildcards are permitted (used instead of Where-Object as such filtering is always faster).
Array subexpression operator #( ). -
Returns the result of one or more statements as an array. The result is always an array of 0 or more objects (i.e. force Powershell to always return an array when a call returns only one object or even $null)
Used [PSCustomObject]#{} in output instead of a sequence of strings (learn advantages at Everything you wanted to know about PSCustomObject).

Powershell Remote Stop and Disable Service

SO Braintrust. I'm not a Powershell person, but I'm working on it. Trying to address yet another zero-day, I'm trying to build a reuseable script to remotely stop and disable the affected service. It is based on a script I got from a Microsoft MVP at (ultimately): http://portal.sivarajan.com/2010/07/stopstart-or-enabledisable-service_26.html
The prompt for the service name was added by me as well as the output information (Write-host & Add-Content lines), so I could get a results summation (the output part's not working fully, but it's the least of my concerns at the moment.).
$output = "c:\scripts\results.csv"
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output Start"
cls
$Cred = Get-Credential
$service = Read-Host -Prompt 'Enter Service Name" '
Import-CSV C:\Scripts\computers.csv | %
{
$computer = $_.ComputerName
Write-Host "Working on $computer"
Add-content -path $output "$computer"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).stopservice()
Add-content -path $output " Stop - $result"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).ChangeStartMode("Disabled")
Add-content -path $output " Disable - $result"
}
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output End"
when I run it, I get an error on the computer name
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'.
The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Scripts\StopAndDisableService.ps1:12 char:54
+ ... result = (Get-WmiObject win32_service -computername $computer -filter ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Scripts\StopAndDisableService.ps1:14 char:54
+ ... result = (Get-WmiObject win32_service -computername $computer -filter ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Computer.csv contains one computer name per line, no punctuation, no FQDN, just the computer name
Special thanks to #Mathias R. Jessen for his help on this. Final working code. you will have to analyze the screen output to catch any errors and see which machines it did not catch due to being offline # time of running (some output file items have been commented out since they don't work as intended)
$output = "c:\scripts\results.csv"
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output Start"
cls
$Cred = Get-Credential
$service = Read-Host -Prompt 'Enter Service Name" '
Import-CSV C:\Scripts\computers.csv -Header ComputerName | % {
$computer = $_.ComputerName
Write-Host "Working on $computer"
Add-content -path $output "$computer"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).stopservice()
#Add-content -path $output " Stop - $result"
$result = (Get-WmiObject win32_service -computername $computer -filter "name='$service'" -Credential $cred).ChangeStartMode("Disabled")
#Add-content -path $output " Disable - $result"
}
Add-content -path $output "======================"
Add-content -path $output "StopAndDisableService Output End"
Analyzing results on the screen output, any results with
Just the machine name - means it's processed without error on that machine (success)
RPC server is unavailable means machine is offline
Cannot call a method on Null-Valued expression on line 12 or line 14 means that service doesn't exist on that machine
The results.csv output file will contain list of names of the machines this script was run against

Move computer to the correct OU from csv file using Powershell

Keep getting "Move-ADObject : Cannot validate argument on parameter 'TargetPath'. The argument is null or empty." when trying to move computers to their respective OU.
Tried these set of codes to achieve it but it doesn't work:
PS C:\temp> cat .\OUs.csv
OUName,Server
AD-DNS,AD-DNS-Server
Apps,App-Server
DBs,DB-Server1
DBs,DB-Server2
Utilities-Servers,Utils-Server
PS C:\temp>
PS C:\temp> $CSVFile = Import-Csv ".\OUs.csv"
PS C:\temp> foreach ($item in $CSVFile){
>> $computer = (Get-ADComputer $item.Server).DistinguishedName
>> $targetOU = (Get-ADOrganizationalUnit -filter "name -eq '$item.OUName'")
>> Move-ADObject -Identity $computer -TargetPath $targetOU.DistinguishedName -Confirm:$false
>> Write-Host "Computer $computer has been moved successfully to $targetOU"
>> }
But if I change
$targetOU = (Get-ADOrganizationalUnit -filter "name -eq '$item.OUName'")
to a specific OU, like this:
$targetOU = (Get-ADOrganizationalUnit -filter "name -eq 'AD-DNS'")
all the computers go to AD-DNS OU.
Here's a session capture when I executed the code:
PS C:\temp>
PS C:\temp> cat .\OUs.csv
OUName,Server
AD-DNS,AD-DNS-Server
Apps,App-Server
DBs,DB-Server1
DBs,DB-Server2
Utilities-Servers,Utils-Server
PS C:\temp>
PS C:\temp> $CSVFile = Import-Csv ".\OUs.csv"
PS C:\temp> foreach ($item in $CSVFile){
>> $computer = (Get-ADComputer $item.Server).DistinguishedName
>> $targetOU = (Get-ADOrganizationalUnit -filter "name -eq '$item.OUName'")
>> Move-ADObject -Identity $computer -TargetPath $targetOU.DistinguishedName -Confirm:$false
>> Write-Host "Computer $computer has been moved successfully to $targetOU"
>> }
Move-ADObject : Cannot validate argument on parameter 'TargetPath'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:4 char:51
+ ... t -Identity $computer -TargetPath $targetOU.DistinguishedName -Confir ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-ADObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.MoveADObject
Computer CN=AD-DNS-Server,CN=Computers,DC=msoc,DC=local has been moved successfully to
Move-ADObject : Cannot validate argument on parameter 'TargetPath'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:4 char:51
+ ... t -Identity $computer -TargetPath $targetOU.DistinguishedName -Confir ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-ADObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.MoveADObject
Computer CN=App-Server,CN=Computers,DC=msoc,DC=local has been moved successfully to
Move-ADObject : Cannot validate argument on parameter 'TargetPath'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:4 char:51
+ ... t -Identity $computer -TargetPath $targetOU.DistinguishedName -Confir ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-ADObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.MoveADObject
Computer CN=DB-Server1,CN=Computers,DC=msoc,DC=local has been moved successfully to
Move-ADObject : Cannot validate argument on parameter 'TargetPath'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:4 char:51
+ ... t -Identity $computer -TargetPath $targetOU.DistinguishedName -Confir ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-ADObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.MoveADObject
Computer CN=DB-Server2,CN=Computers,DC=msoc,DC=local has been moved successfully to
Move-ADObject : Cannot validate argument on parameter 'TargetPath'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:4 char:51
+ ... t -Identity $computer -TargetPath $targetOU.DistinguishedName -Confir ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-ADObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.MoveADObject
Computer CN=Utils-Server,CN=Computers,DC=msoc,DC=local has been moved successfully to
PS C:\temp>
Expectation is that Server should get moved to it's corresponding OU.
Appreciate your help! Thank you.
Update1:
I tried changing the code to the following:
$CSVFile = Import-Csv ".\OUs.csv"
foreach ($item in $CSVFile){
$computer = (Get-ADComputer $item.Server).DistinguishedName
$targetOU = (Get-ADOrganizationalUnit -filter "name -eq '$item.OUName'").DistinguishedName
Move-ADObject -Identity $computer -TargetPath $targetOU -Confirm:$false
Write-Host "Computer $computer has been moved successfully to $targetOU"
}
still got the same error.
Update 2:
This works:
$CSVFile = Import-Csv ".\OUs.csv"
foreach ($item in $CSVFile){
$computer = (Get-ADComputer $item.Server).DistinguishedName
$targetOU = Get-ADObject -Filter "Name -eq '$($item.OUName)'"
Move-ADObject -Identity $computer -TargetPath $targetOU.DistinguishedName -Confirm:$false
Write-Host "Computer $computer has been moved successfully to $targetOU"
}
When accessing a property in a variable inside a quoted string, you have to escape it with $(...) to have it evaluated as an expression. So your code becomes:
$targetOU = (Get-ADOrganizationalUnit -filter "name -eq '$($item.OUName)'")

Missing Terminator and Missing Closing in PowerShell

I'm quite new to PowerShell, so apologies if this should be obvious to me.
I have the following PowerShell script;
$FieryChasm = {
Clear-Host
Write-Host "`n This script is for dropping user accounts from the Active Directory.`n`n`n It will :`n`n - Disable the AD account`n - Reset the AD password`n - Move the account to the Disabled OU`n - Set the expiry date on the account to yesterday's date`n - Remove all # groups`n- Hide the user from the email exchange`n`n`n`n Input the UserID`n"
$UserID = Read-Host -Prompt ' '
Clear-Host
$title = "`n You input '$UserID'"
$message = "`n`n Are you certain you want to process this UserID as a leaver?`n`n`n`n"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription " &Yes", `
"Yes, process this userID as a leaver.`n"
$no = New-Object System.Management.Automation.Host.ChoiceDescription " &No", `
"No, take me back a step so I can input the UserID again.`n"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 1)
Clear-Host
switch ($result)
{
0 {
Write-Host "`n Disabling account...`n"
Disable-ADAccount -Identity $UserID
Write-Host "`n Moving to OU 'Disabled Accounts'...`n"
Move-ADObject -Identity $UserID -TargetPath "OU=Disabled Accounts,DC=my-company,DC=co,DC=uk"
Write-Host "`n Resetting password...`n"
$YouShallNotPass = (Get-Random -input "Da$her","Danc%r","Pr$ncer","V!xen","C$met","Cup!d","Donn%r","Bl!tzen") + (Get-Random -Minimum 1000 -Maximum 999999) + (Get-Random -input "Da$her","Danc%r","Pr$ncer","V!xen","C$met","Cup!d","Donn%r","Bl!tzen")
Set-ADAccountPassword -Reset -NewPassword $YouShallNotPass –Identity $UserID
Write-Host "`n Setting expiry date...`n"
$Yesterday = (Get-Date).AddDays(-1).ToString('dd/MM/yyyy')
Set-ADAccountExpiration $UserID -DateTime $Yesterday
Write-Host "`n Removing AD groups...`n"
Get-ADuser $UserID -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name} | clip
Get-ADGroup -Filter 'name -like "#*"' | Remove-ADGroup -identity $UserID
Write-Host "`n Hiding user from Exchange...`n"
Set-Mailbox -Identity DOMAIN\$UserID -HiddenFromAddressListsEnabled $true
Write-Host "`n Completed.`n`n $UserID has been processed as a leaver.`n`n`n Press any key to go back to the fiery chasm from whence you came ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
1 {
Write-Host "`n You selected No.`n`n User was NOT set as a leaver.`n`n`n Press any key to go back to the fiery chasm from whence you came ..."
}
}
.$FieryChasm
}
and I'm getting the following errors...
At C:\Users\user\Desktop\LeaverScript.ps1:64 char:148
+ ... ce you came ..."
+ ~
The string is missing the terminator: ".
At C:\Users\user\Desktop\LeaverScript.ps1:34 char:8
+ 0 {
+ ~
Missing closing '}' in statement block.
At C:\Users\user\Desktop\LeaverScript.ps1:33 char:5
+ {
+ ~
Missing closing '}' in statement block.
At C:\Users\user\Desktop\LeaverScript.ps1:1 char:15
+ $FieryChasm = {
+ ~
Missing closing '}' in statement block.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
Could someone explain why, and give some tips on me not making the same mistake again?
Thank you.
Ah, got it!
On line 37, which was this;
Set-ADAccountPassword -Reset -NewPassword $YouShallNotPass -Identity $UserID
the dash before 'Identity' was an incorrect Unicode character. I replaced it and the errors went away :)

Check if OU exists not working properly

Wrote this small script to test if an OU exists, if exists write to console and terminate. If not exists create OU and do some other stuff. Though can't seem to understand why i cant get it working.
For some reason the output will always tell me that the OU exists, and I am pretty sure it does not. Am I doing something terribly wrong?
This is the code:
param (
[parameter(mandatory=$true)] [string] $servername
)
Import-Module ActiveDirectory
Function CheckOU {
$script:OUpath = "OU=$servername,OU=Rechtengroepen,OU=danny,dc=Doenoe,DC=com"
$Status = $false
$GetOU = Get-ADOrganizationalUnit -Identity $OUpath -ErrorAction SilentlyContinue
if ($GetOU -eq $null) {
$status = $false
Write-Host -ForegroundColor Green "$OUpath does not exist."
} else {
$Status = $true
Write-Host -ForegroundColor Red "$OUpath exists!"
}
return $Status
}
$OUStatus = CheckOU
if ($OUStatus -eq $true) {
Write-Host "$OUpath exists. Function working."
} else {
Write-Host "$OUpath does not exsist, do something."
}
Output:
Get-ADOrganizationalUnit : Directory object not found
At C:\Scripts\CreateOUgroups\createadgroups_test02.ps1:10 char:14
+ $GetOU = Get-ADOrganizationalUnit -Identity $OUpath -ErrorAction SilentlyCon ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (OU=notexistsing...c=Doenoe,DC=com:ADOrganizationalUnit) [Get-ADOrganizationalUnit], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADOrganizationalUnit
OU=notexistsingOU,OU=Rechtengroepen,OU=danny,dc=Doenoe,DC=com exists!
OU=notexistsingOU,OU=Rechtengroepen,OU=danny,dc=Doenoe,DC=com exists. Function working.
Using the cmdlet with the -Identity parameter causes a terminating error if the object with the given identity doesn't exist. Use -Filter to avoid this issue:
Get-ADOrganizationalUnit -Filter "distinguishedName -eq '$OUPath'"