script tuning for include all computers in domain - powershell

I have a script which scans given computers in domain for identifying and disables mobile hotspot function in windows 10. Script works properly , but i want to scan all my domain comupters, not only specified.. can anyone help me for adjusting this script?
$username = "domain\administrator"
$password = "Your password"
$credential = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $password
$computers = #("nr1", "nr2", "nr3")
foreach($computer in $computers){
$hotspot = Invoke-Command -ComputerName $computer -credential $credential -scriptblock {
$hotspot = Get-Service "icssvc"
if($hotspot.Status -eq "Running"){
Write-Host "Hotspot is turned on on $computer" -ForegroundColor Red
try{
Stop-Service "icssvc"
Write-Host "Successfully stopped service on $computer" -ForegroundColor Green
}catch{
Write-Host "Unable to stop service on $computer" -ForegroundColor Red
}
}else{
Write-Host "No Hotspot running on $computer" -ForegroundColor Green
}
}

If you replace $computers = #("nr1", "nr2", "nr3") with something like:
Import-Module ActiveDirectory
$computers = Get-ADComputer -Properties DNSHostName
That should return an array of hostnames. You may need to provide credentials via -Credential, and you can -Filter the results if you need to exclude any machines.
See docs and examples of Get-ADComputer here.

Related

Adding a success or fail message to a script

I have the below very simple script that changes hostname and workgroup to multiple pcs. I want to add to that script a success or fail message but I can't find a way to do that. Can someone help?
$cred = Get-Credential domain\user
$computers = Import-Csv "C:\12.txt" -Header Oldname,Newname
foreach ($name in $computers) {
Add-computer -computername $name.Oldname -workgroupname workgroup -newname $name.Newname -credential $cred -restart -force
}
Append switch -PassThru to the Add-Computer cmdlet.
Normally, this cmdlet does not output anything, but with the PassThru switch, it will return a
ComputerChangeInfo
object from which you can check the .HasSucceeded property.
$cred = Get-Credential domain\user
$computers = Import-Csv -Path "C:\12.txt" -Header Oldname,Newname
foreach ($name in $computers) {
# use splatting on cmdlets that take a lot of parameters
$params = #{
Computername = $name.Oldname
WorkgroupName = $workgroup
NewName = $name.Newname
Credential = $cred
Restart = $true
Force = $true
PassThru = $true
}
try {
$machine = Add-Computer #params -ErrorAction Stop
if ($machine.HasSucceeded) {
Write-Host "Successfully added computer '$($machine.ComputerName)'" -ForegroundColor Green
}
else {
Write-Host "Adding computer '$($machine.ComputerName)' failed!" -ForegroundColor red
}
}
catch {
Write-Warning "Error adding computer $($name.Oldname):`r`n$($_.Exception.Message)"
}
}
You can also experiment with adding switch -Verbose to get more detailed information returned from Add-Computer

Unable to fetch IIS status from Remote server using Powershell

I am trying to fetch IIS status from remote server using powershell.
I have used command Get-Service but i don't recieve any output from this command.
Below is my code block.
$pass='pass'|ConvertTo-SecureString -AsPlainText -Force;
$Credentials = New-Object
System.Management.Automation.PsCredential("user",$pass);
$Service=invoke-command -computername "server" -credential $Credentials -
scriptblock {Get-Service|Where-Object Name -eq 'IISADMIN'}
if($Service.Status -eq 'Running')
{
write-host "IIS Running"
}
else
{
throw "IIS not running or Not installed"
}
I Checked your code and did not see any problem with it, Did you checked the service exists locally using Get-Service or Service Manager?
Anyway you don't have to use Invoke-Command for this, you can use the built in -ComputerName parameter of the Get-Service cmdlet,
And if you need to provide credentials, you can use WMI:
$Credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
$Service = Get-WmiObject -Class win32_service -ComputerName Server -Filter 'Name = "W3SVC"' -Credential $Credentials
Try using a WMI call instead, I have found it far more reliable when working with remote servers.
$Service = Get-WmiObject -Computername $computer -Credential $credentials Win32_service -ErrorAction Continue | Where {$_.Name -eq 'IISADMIN'}

stop or start a service on remote machine

I created a script that will start or stop a service based on it's display name. My script works on the local machine but I would like to make sure that it can be done on a remote machine and the local machine. I am not sure how to get it working on a remote machine.
any help would be appreciated.
$serviceName = Read-Host -Prompt 'Please enter service name: '
# Check that service name exists
If (Get-Service $serviceName -ErrorAction SilentlyContinue)
{
# Check that service name is not empty
if([string]::IsNullOrEmpty($serviceName))
{
Write-Host "Service name is NULL or EMPTY"
}
else
{
$Choice = Read-Host -Prompt 'Would you like to start or stop the service'
#Start service
If ($Choice -eq 'start') {
Start-Service -displayname $serviceName
Write-Host $serviceName "Starting..." -ForegroundColor Green
}
#Stop service
If ($Choice -eq 'stop') {
Stop-Service -displayname $serviceName
Write-Host $serviceName "Stopping..." -ForegroundColor Green
}
}
}
else {
Write-Host "Service name does not exist"
}
You can't use Start-Service/Stop-Service for a remote computer, you can however pass a service object from Get-Service (using the ComputerName parameter) to Set-Service which can perform the same start/stop actions for a remote computer:
Get-Service $ServiceName -ComputerName $ComputerName | Set-Service -Status Running
I find this to be much easier than using PowerShell Remoting or WMI commands.
You can easily update your code with minimal code changes:
$serviceName = Read-Host -Prompt 'Please enter service name: '
#get computername or use localhost for local computer
if(($ComputerName = Read-Host 'Enter Computer Name, leave blank for local computer') -eq ''){$ComputerName = 'localhost'}
$Service = Get-Service -DisplayName $serviceName -ComputerName $ComputerName -ErrorAction SilentlyContinue
# Check that service name exists
if ($Service) {
# Check that service name is not empty
if([string]::IsNullOrEmpty($serviceName)){Write-Host 'Service name is NULL or EMPTY'}
else {
$Choice = Read-Host -Prompt 'Would you like to start or stop the service'
#Start service
If ($Choice -eq 'start') {
$Service | Set-Service -Status Running
Write-Host $serviceName 'Starting...' -ForegroundColor Green
}
#Stop service
If ($Choice -eq 'stop') {
$Service | Set-Service -Status Stopped
Write-Host $serviceName 'Stopping...' -ForegroundColor Green
}
}
}
else {
Write-Host 'Service name does not exist'
}
Assuming that you have not disabled PowerShell remoting, the easiest way to do it is to wrap it in a function with ComputerName as an optional parameter, and then use Invoke-Command and splat PSBoundParameters.
Function Toggle-Service{
[cmdletbinding()]
Param([string[]]$ComputerName)
$serviceName = Read-Host -Prompt 'Please enter service name: '
# Check that service name exists
If (Invoke-Command -ScriptBlock {Get-Service $serviceName -ErrorAction SilentlyContinue} #PSBoundParameters)
{
# Check that service name is not empty
if([string]::IsNullOrEmpty($serviceName))
{
Write-Host "Service name is NULL or EMPTY"
}
else
{
$Choice = Read-Host -Prompt 'Would you like to start or stop the service'
#Start service
If ($Choice -eq 'start') {
Invoke-Command -ScriptBlock {Start-Service -displayname $serviceName} #PSBoundParameters
Write-Host $serviceName "Starting..." -ForegroundColor Green
}
#Stop service
If ($Choice -eq 'stop') {
Invoke-Command -ScriptBlock {Stop-Service -displayname $serviceName} #PSBoundParameters
Write-Host $serviceName "Stopping..." -ForegroundColor Green
}
}
}
else {
Write-Host "Service name does not exist"
}
}
Then you can call Toggle-Service without a parameter to perform it locally, or include the name of a remote server to perform the actions on that server.
Start-Service and Stop-Service do not work against remote computers. You will either need to do PowerShell remoting, or use WMI. In my environment, PowerShell remoting is blocked by default, but we use WMI instead; service objects retrieved through Get-WMIObject have a method called Start-Service() which can be called on the retrieved service object:
(Get-WmiObject -ComputerName $ComputerName -Class Win32_Service -Filter "Name='$ServiceName'").StartService()
Stopping a service on a remote computer using WMI works the same way; you would call the service object's StopService() method instead.
I recommend that you read the information in Get-Help Get-WMIObject and the MSDN reference on the Win32_Service class.
ETA: It should be noted that by omitting the -ComputerName parameter, WMI will work on the local computer as well.

Check the AppPool status through power-shell and start that on remote machine

The requirement is to extract the server name one by one and check the AppPool status, if that is found to be stopped, make it running. below code is not helping out.
$ErrorActionPreference = "Continue"
$status = gc -path "D:\Servers\server.txt"|ForEach-Object (invoke-command -ComputerName $_ -ScriptBlock {Import-Module Webadministration Get-WebAppPoolState -name (gc "D:\AppPool.txt")})
if ($status.value -eq "Started")
{
Write-Host ("ApppPool already running")
}
else
{
Invoke-Command -ScriptBlock {Start-WebAppPool}
Write-host ("AppPool has started successfully")
}
There were multiple problems with your code, I've gone through them individually so you can see what was stopping it from working correctly.
The syntax for foreach was wrong, you needed to use {} not () in this case. Normal brackets are only used like this ForEach ($number in $numArray ) {CODE} which you aren't.
You were checking $status outside the foreach loop - so it so was evaluating $status only once (with the final computers AppPool status) rather than for each computer.
Your second Invoke-Command didn't have a ComputerName parameter specified so was only running the command locally not against the remote computer, meaning the AppPool would never be started.
As you were specifying the AppPool name using gc "D:\AppPool.txt" this file would have to be present on every remote computer for it to work. I've changed this to be passed into the command as an argument so the file only needs to be on the computer running the script.
$Credentials = Get-Credential
$AppPools = Get-Content "D:\AppPool.txt"
$Servers = Get-Content -Path "D:\Servers\server.txt"
ForEach ($Server in $Servers) {
ForEach ($AppPool in $AppPools) {
$AppPoolState = Invoke-Command -ComputerName $Server -ScriptBlock {Import-Module WebAdministration; Get-WebAppPoolState -Name $args[0] } -ArgumentList $AppPool -Credential $Credentials
if ($AppPoolState.Value -eq "Started")
{
Write-Host "$AppPool AppPool already running on $Server"
}
else
{
Invoke-Command -ComputerName $Server -ScriptBlock {Start-WebAppPool -Name $args[0] } -ArgumentList $AppPool -Credential $Credentials
Write-Host "$AppPool AppPool started on $Server"
}
}
}
Note: I run a non-privileged account so have to supply Credentials. If the account you're running the script as has appropriate permissions to all the remote computers you can remove the three Credentials references.

Remove-ADComputer : Access is denied powershell

Long time lurker but I finally found a problem that I could not find an answer for so I decided it was time to join. Im trying to collect a list of computers in AD that are older than X days ($DelCompDays). Then based off of the DistinguishedName field delete that computer using the Identity flag. Problem is even with domain admin creds I am getting: Remove-ADComputer : Access is denied
Even if I run Remove-ADComputer -Identity "Full CN or Short name" I get an access denied. Anyone have any ideas? Thank you in advance!
#Get AD computers older than $DelCompDays
$results = Search-ADAccount -ComputersOnly -AccountInactive -TimeSpan "$DelCompDays.00:00:00"
#Loop and try to delete
foreach ($result in $results){
if ($result -ne $NULL){
try {
Remove-ADComputer -Identity $result.DistinguishedName -confirm:$false
$Success = "Deleted: $result.DistinguishedName"
WriteCustomOutput -message "$Success" -foregroundcolor green -backgroundcolor DarkMagenta
}
catch {
$Error = "Failed to delete: $result.DistinguishedName"
WriteCustomOutput -message "$Error" -foregroundcolor Red -backgroundcolor Black
}
}
else{
$Warning = "No computers older than $ArcDays days to delete"
WriteCustomOutput -message "$Warning" -foregroundcolor yellow -backgroundcolor DarkMagenta
}
}
Figured it out. When running non-interactive you need to specify the creds in the command call.
$secpasswd = ConvertTo-SecureString "ClearTextPass" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("Username", $secpasswd)
Remove-ADComputer -Identity $result.DistinguishedName -Recursive -confirm:$false -credential $creds