Assistance in properly scripting a Join and Un-Join Domain script - powershell

Hello guys i have started to create a script that would basically automate the un-join and joining of a computer via a script this initially works fine right up until the point i need to start pinging for the computer to come back online. For the instance of un-joining it works fine but all the issue arise when trying to join.
Maybe fresh pair of eyes can lend me some Intel on the matter thank you.
<#
############################################################################################################
# Written by CPineda # NOTE: This only works if computer is on the wire. #
# This Script un-joins and re-joins the domain. # So its very important that we connect the devce #
# Created: 04/27/2016 # to the LAN. #
# Last revision 4/6/2016 # #
############################################################################################################
#>
# Set up your Variables
$ComputerIP = "" #Stores the Computers IP
$ComputerName = "" #Stores the Name of the computer you will be working with.
#$LocalCredentials = "" #Stores the Local Administrator credentials. (As Neeeded)
$DomainCredentials = "" #Stores the Domain Administrator credentials.
# Get information needed for the script to run.
while ($ComputerIP -eq ""){
Clear-Host #Clear the PS Console Window
$ComputerIP = Read-Host "Enter the name of the Computer IP"
}
while ($ComputerName -eq ""){
Clear-Host #Clear the PS Console Window
$ComputerName = Read-Host "Enter the name of the Computer"
}
<# while ($LocalCredentials -eq ""){
Clear-Host #Clear the PS Console Window
$LocalCredentials = Read-Host "Enter the User name of the Local User Admin Account"
}
#>
while ($DomainCredentials -eq ""){
Clear-Host #Clear the PS Console Window
$DomainCredentials = Read-Host "Enter the User name of the Domain User Admin Account"
}
# Remove the computer from the Domain.
Remove-Computer -ComputerName $ComputerName -LocalCredential $ComputerName\administrator -UnJoinDomainCredential kelsonfla\$DomainCredentials -WorkgroupName WORKGROUP -Force -Restart
Read-Host "Hit ENTER to continue"
# Ping until computer returns on the wire.
Clear-Host
Write-Host "At this time we will ping the compputer in question untill it returns back online"
Write-Host "Hit ENTER to continue"
Read-Host
Test-Connection ($ComputerIP) {
$result = Test-Connection $ComputerIP -Count 3 -Delay 10 -Quiet
if ($Result | where { $_ -match 'Reply from ' }){$true}
else {$false}
}
Write-Verbose "The computer $ComputerIP has went down for a reboot. Waiting for it to come back up..."
while (!(Test-Connection -ComputerName $ComputerIP)) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for $ComputerIP to come back online"
}
Write-Verbose "The computer $ComputerIP has come online. Waiting for OS to initialize"
$EapBefore = $ErrorActionPreference
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue
while (!(Get-WmiObject -ComputerName $ComputerIP -Class Win32_OperatingSystem -Credential $LocalCredentials)) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for OS to initialize..."
$ErrorActionPreference = $EapBefore
}
# Add computer back to the Domain.
Add-Computer -ComputerName $ComputerIP -LocalCredential $ComputerName\administrator -DomainName kelsonfla.local -Credential kelsonfla\$DomainCredentials -Restart -Force
Read-Host "Hit ENTER to continue"
# Ping until computer returns on the wire.
Clear-Host
Write-Host "At this time we will ping the compputer in question untill it returns back online"
Write-Host "Hit ENTER to continue"
Read-Host
Test-Connection ($ComputerIP) {
$result = Test-Connection $ComputerIP -Count 3 -Delay 10 -Quiet
if ($Result | where { $_ -match 'Reply from ' }){$true}
else {$false}
}
Write-Verbose "The computer $ComputerIP has went down for a reboot. Waiting for it to come back up..."
while (!(Test-Connection -ComputerName $ComputerIP)) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for $ComputerIP to come back online"
}
Write-Verbose "The computer $ComputerIP has come online. Waiting for OS to initialize"
$EapBefore = $ErrorActionPreference
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue
while (!(Get-WmiObject -ComputerName $ComputerIP -Class Win32_OperatingSystem -Credential $LocalCredentials)) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for OS to initialize..."
$ErrorActionPreference = $EapBefore
}
Clear-Host
Write-Output "If you are Reading this then you have successfully Unjoined and Re-Joined a Computer to the Network"
Start-Sleep -Seconds 3
Clear-Host

First : for the ping part, you should remove the code :
Test-Connection ($ComputerIP) {
$Result = ping $ComputerIP -n 3
if ($Result | where { $_ -match 'Reply from ' }) {
$true
} else {
$false
}
}
and simply use
!$result = $false
do {
Write-Verbose "Waiting for $ComputerIP to come back online"
$result = Test-Connection $ComputerIP -Count 2 -Delay 5 -Quiet
} while (!$result)
And then use the value of the $result boolean to see if your computer is reponding again. Test-Connection is a Cmdlet that cover the ping role.

Related

Powershell Delete Computer Object

Can some one help me on the next code im trying to run..
it seem's to be ok for me but does not delete the Object when i execute-it
Import-Module ActiveDirectory
Clear-Host
$Computer = Read-Host "Type in the Host to Delete"
$rute = Get-ADComputer -Identity:"CN=$Computadora,OU=GDL,OU=ClientComputers,OU=ZAP,OU=MX,DC=kabi,DC=ads,DC=fresenius,DC=com" -Server:"DCKABI02.kabi.ads.fresenius.com"
if($rute.Contains($Computer)){
Clear-Host
Remove-ADComputer -Identity=$Computadora,OU=GDL,OU=ClientComputers,OU=ZAP,OU=MX,DC=kabi,DC=ads,DC=fresenius,DC=com" -Server:"DCKABI02.kabi.ads.fresenius.com" -Confirm:$false
#Clear-Host
Write-Host "The Computer Exist and it has been deleted" -ForegroundColor Green
Start-Sleep -Seconds 5
} else{
Clear-Host
Write-Host "The Host does not exist on AD" -ForegroundColor Red
Start-Sleep -Seconds 3
}
try to delete a Active directory object.. expected to work
Your code is not very clear and seems overengineered, $rute.Contains($Computer) will never ever be $true, you probably meant $rute.DistinguishedName.Contains($Computer) which could be $true but .Contains is case-sensitive so it could also be $false.
Your Read-Host statement is assigned to $Computer but then you're using $Computadora. Also, it's unclear why you are hardcoding OU=GDL,OU=ClientComputers,OU=ZAP,OU=MX,DC=kabi,DC=ads,DC=fresenius,DC=com, I would assume you want to use this OU as your -SearchBase.
Here is how you can approach and will most likely work:
$param = #{
SearchBase = "OU=GDL,OU=ClientComputers,OU=ZAP,OU=MX,DC=kabi,DC=ads,DC=fresenius,DC=com"
LDAPFilter = "(name={0})" -f (Read-Host "Type in the Host to Delete")
Server = "DCKABI02.kabi.ads.fresenius.com"
}
$computer = Get-ADComputer #param
if($computer) {
Clear-Host
$computer | Remove-ADComputer -Server "DCKABI02.kabi.ads.fresenius.com" -Confirm:$false
Write-Host "The Computer Exist and it has been deleted" -ForegroundColor Green
Start-Sleep -Seconds 5
}
else {
Clear-Host
Write-Host "The Host does not exist on AD" -ForegroundColor Red
Start-Sleep -Seconds 3
}

Logic Issue with PowerShell

When I run this, if there is a connection, ($TRUE) the logic should go to whether the user is logged in. It moves to the Else statement which says the computer is offline? Can someone help me find the missiing link in the script? I am lost on this one. True should say online, then if user is logged in the message should be Computer in use. It is showing everyone as OFFLINE?
Function Get-RemoteLogonStatus{
ForEach ($line in Get-Content C:\ADComputers.csv)
{$Computername = $line
if(Test-Connection -ComputerName $ComputerName -Count 2 -Quiet){
If((Get-WmiObject -Class Win32_ComputerSystem -ComputerName
$ComputerName).username -eq $null)
{
Write-Output 'No user logged in. RESTART COMPUTER'
##Shutdown /r /t 0 /M \\$ComputerName
$ComputerName
}
Write-Output 'Computer in Use.'
$ComputerName
}
else{
Write-Output 'Computer OFFLINE.'
$ComputerName
}
}
}

Scanning For a Service on Online Devices with Powershell Script

I wrote a script to tell me if the SEP Master Service is running for all computer listed in a file, start the service if its stopped, and let me know if it doesn't exist. It's working, but when the script hits a computer that is not online, it slows down until an error is returned and then finally goes to the next computer in the list. Is there a way to only scan for the service on the deivces in the list that are online and can be pinged on the network?
$computers = Get-Content -Path "C:\temp2\ComputerList.txt"
foreach ($computer in $computers) {
$service = Get-Service -name SepMasterService -computername $computer
$ServiceStatus = $service.Status
$ServiceDisplayName = $service.DisplayName
if ($ServiceStatus -eq 'Running') {
Write-Output "Service OK - Status of $ServiceDisplayName is $ServiceStatus on $computer"
}
elseif ($ServiceStatus -eq 'stopped') {
Start-Service -Name SepMasterService -PassThru
}
else {
Write-Output "Symantec Endpoint Protection doesn't exist on $computer"
}
}
Add a check for online machines using the test-connection cmdlet and go to the next computer.
$computers = Get-Content -Path "C:\temp2\ComputerList.txt"
foreach ($computer in $computers) {
if(!(Test-Connection -ComputerName $computer -Count 1 -Quiet))
{
Write-Output "$computer is offline"
continue
}
$service = Get-Service -name SepMasterService -computername $computer
$ServiceStatus = $service.Status
$ServiceDisplayName = $service.DisplayName
if ($ServiceStatus -eq 'Running') {
Write-Output "Service OK - Status of $ServiceDisplayName is $ServiceStatus on $computer"
}
elseif ($ServiceStatus -eq 'stopped') {
Start-Service -Name SepMasterService -PassThru
}
else {
Write-Output "Symantec Endpoint Protection doesn't exist on $computer"
}
}
The -Count parameter specifies how many time to ping the computer. The default is 4 but this will speed up your process. The continue statement will stop executing any of the code in the current iteration of the foreach loop and go to the next computer.
Hope this helps.

Trying ru script in the loop to see if services on Remote Server (s) is running

Originally I had a script:
Do {
Get-Date
Write-Output "SERVER01";
gsv -cn SERVER01 -Name Dm* |out-string
Write-Output "SERVER02";
gsv -cn SERVER02 -Name Dm* |out-string
sleep 60
}
while ($true)
I am trying to make Server(s) name and service a variable
Do {
Get-Date
$name = Read-Host 'What is your ServerName?'
$srv = Read-Host 'What is ServiceName?'
write-host $name
gsv -cn $name -Name $srv |out-string
sleep 60
}
Please help me to make it work.
There's nothing wrong with your code other than you assumedly only want to prompt for the server name and service name once and then check them repeatedly. In which case, move your read-host lines to before the Do loop:
$name = Read-Host 'What is your ServerName?'
$srv = Read-Host 'What is ServiceName?'
Do {
Get-Date
Write-Host $name
gsv -cn $name -Name "$srv*" | Out-String
Sleep 60
}
while ($true)
I've also added the wildcard * character back into your retrieval of the services, per your original script, so that you can return services based on a partial name.

how to automate Wusa with remoting and overcoming the lack of wait cmd

Scenario: Taking a list of kb files and executing them remotely with WUSA install of target machines across network.
The flow is like this:
enter a powershell session W/ target computer
for each loop $KB in $List
wusa.exe $kb
wait 'til installed
back to the wusa.exe for next device in $list
Code:
# SET UP ERROR-HANDLING FOR THE PS SESSION
$ErrorActionPreference = "continue"
# DECLARE VARIABLE THAT CONTAINS LIST OF PATCHES AVAILABLE FOR INSTALL
$PatchList = (Get-ChildItem -Path C:\WinPatch -recurse | Where-Object {$_.Extension -eq '.msu'})
# ESTABLISH LOOP TO ITERATE THRU PATCHES
foreach ($Patch in $PatchList)
{
Try
{
Write-Host ("`n Preparing to install: " + $Patch) -ForegroundColor Yellow
Write-Host ("`n Installing...") -ForegroundColor Magenta
$SB = {
$arglist = "$Patch", "/quiet", "/norestart"
Start-Process -FilePath "C:\windows\system32\wusa.exe" -ArgumentList $arglist -Wait}
Invoke-Command -ScriptBlock $SB
Write-Host "`n Installation complete`n" -ForegroundColor Green
}
Catch
{
[System.Exception]
Write-Host "Installation failed with Error -- $Error()" -ForegroundColor Red
$Error.Clear()
}
}
# RESTART OPTIONS
$Ans1 = Read-Host "`n Would you like to restart this computer now (Type Y for yes or N for no)"
if ($Ans1 -eq 'Y' -or $Ans1 -eq 'y')
{
Remove-Item -Path C:\WinPatch\*.msu -Force
Write-Host "`n This computer will restart in 5 seconds..." -ForegroundColor Yellow
Start-Sleep -Seconds 5
Restart-Computer -Force
}
else
{
# TEST COMPUTER FOR PS VERSION
$Tester = test-wsman -computername localhost | Select-Object -Property ProductVersion
if ($Tester.ProductVersion.EndsWith("1.0"))
{
Write-Host "`n This computer has PS v1.0 installed and you will have to open Task Scheduler to schedule restart" -ForegroundColor Red
Read-Host "`n Press ENTER to continue..."
}
elseif ($Tester.ProductVersion.EndsWith("2.0"))
{
Write-Host "`n This computer has PS v2.0 installed and you will have to open Task Scheduler to schedule restart" -ForegroundColor Red
Read-Host "`n Press ENTER to continue..."
}
else
{
# SCHEDULE RESTART
Import-Module PSScheduledJob
$RST = Read-Host -Prompt "`n Enter date/time to restart computer...format is --> mm/dd/yyyy hh:mmAM/PM"
$Ans2 = Read-Host -Prompt "`n You entered: $RST... if this is correct, enter Y for yes"
if ($Ans2 -eq 'Y' -or $Ans2 -eq 'y')
{
$Nomen = Read-Host -Prompt "`n Enter name for scheduled restart "
$Trig = New-JobTrigger -Once -At $RST
Register-ScheduledJob -Name $Nomen -Trigger $Trig -ScriptBlock { Restart-Computer -force } -RunAs32
}
else
{
Write-Host "`n Please restart the script and try again" -ForegroundColor Red
}
}
}
Break
PsExec.exe -u $domain\$username -p $password -h -s -accepteula \\$computer wusa.exe /quiet 'C:\Program Files\WindowsPowershell\Modules\windows10.0-kb5005112-x64.msu' /wait /forcerestart
This works for me. If you wrap this in an Invoke-Command block you can run this remotely. :-)
Thanks,