I am attempting to use a PowerCLI script to create Virtual Machines based off of a CSV file. The current code that I am working with has the 'Connect-VIServer' hard-coded as a variable in the script "$vcenter_srv = 'vcenter.seba.local'":
$ScriptRoot = Split-Path $MyInvocation.MyCommand.Path
$csvfile = "$ScriptRoot\vms2deploy.csv"
$vcenter_srv = 'vcenter.seba.local'
$timeout = 1800
$loop_control = 0
$vmsnapin = Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
$Error.Clear()
if ($vmsnapin -eq $null)
{
Add-PSSnapin VMware.VimAutomation.Core
if ($error.Count -eq 0)
{
write-host "PowerCLI VimAutomation.Core Snap-in was successfully enabled." -ForegroundColor Green
}
else
{
write-host "ERROR: Could not enable PowerCLI VimAutomation.Core Snap-in, exiting script" -ForegroundColor Red
Exit
}
}
else
{
Write-Host "PowerCLI VimAutomation.Core Snap-in is already enabled" -ForegroundColor Green
}
if ($env:Processor_Architecture -eq "x86") {
#Connect to vCenter
Connect-VIServer -Server $vcenter_srv
I am trying to determine if there is a way to cause the PowerCLI script to prompt for the server name with the 'Connect-VIServer' command when it occurs in the script "Connect-VIServer -Server $vcenter_srv" and then continue with the remaining values pulled from the CSV file.
Thank you for any information you may provide,
You can prompt for an aswer by doing a Read-Host and storing it in a variable which the Connect-VIServer cmdlet can use as below:
$vc = read-Host "vCenter Server?"
Connect-VIServer -Server $vc
Related
I've used this setup with a foreach statement multiple times and never had any issues. It points to a text file with multiple lines of input. However, this script only outputs the hard disk information for the first input line in the text file, and then stops. What's going on here?
# Create log file directory
New-Item -Path "C:\scripts\logs" -ItemType "directory" -ErrorAction SilentlyContinue
# Set script name
$ScriptName = "Hard_Disk_Count.ps1"
# Set script log file
$LogFile = "C:\scripts\logs\Hard_Disk_Count.log"
# Clear script log file
Clear-Content -Path "C:\scripts\logs\Hard_Disk_Count.log"
# Import VMware modules
Write-Host "Importing VMWare modules." -ForegroundColor Cyan
Import-Module VMware.VumAutomation
Import-Module VMware.VimAutomation.Core
Import-Module VMware.VimAutomation.Storage
Import-Module VMware.VimAutomation.Common
Import-Module VMware.VimAutomation.License
# Connect to a vCenter
$VIServer = "example"
Connect-VIServer -Server $VIServer
Try {
# Prompt for confirmation that input file is updated
$confirmation = Read-Host "Please confirm that the text file located at 'C:\scripts\input.txt' contains the correct information.`nEnter 'y' to proceed."
if ( $confirmation -eq 'y' ) {
$InputFile = Get-Content "C:\scripts\input.txt"
foreach( $I in $InputFile ){
# Example write to log file
Write-Host "Script $ScriptName started. Log file located at $LogFile." -ForegroundColor Cyan
"$(Get-Date) - Script $ScriptName started." >> $LogFile
$ClusterName = "$I"+"_Cluster"
$VM =
Get-Cluster $ClusterName |
Get-VM |
Where-Object { $_.Name -like "*190*" }
$Disks = Get-HardDisk -VM $VM
$DiskCount = $Disks.count
"$VM, $DiskCount" >> $LogFile
}
}
}
Catch {
# Error email message send
}
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.
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,
I have been trying to make a powershell script to detect what antivirus software is installed, and then uninstall it.
I have been able to detect what antivirus is installed using WMI.
I cant find a way to uninstall antivirus software via powershell however.
Is there a way to do this?
Hope you guys can help.
The script i use to detect antivirus:
function Get-AntivirusName {
[cmdletBinding()]
param (
[string]$ComputerName = "$env:computername" ,
$Credential
)
BEGIN
{
$wmiQuery = "SELECT * FROM AntiVirusProduct"
}
PROCESS
{
$AntivirusProduct = Get-WmiObject -Namespace "root\SecurityCenter2" -Query $wmiQuery #psboundparameters
[array]$AntivirusNames = $AntivirusProduct.displayName
Switch($AntivirusNames) {
{$AntivirusNames.Count -eq 0}{"No Antivirus installed";Continue}
{$AntivirusNames.Count -eq 1 -and $_ -eq "Windows Defender"} {"Only Windows Defender is installed!";Continue}
{$_ -ne "Windows Defender"} {"Antivirus installed ($_)."}
}
}
END {
}
}
$av = Get-AntivirusName
Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show($av,'Antivirus')
You could try the following, from https://community.spiceworks.com/scripts/show/3161-detect-and-remove-software-powershell:
################################################
# Powershell Detect and Remove software script #
# #
# V1.0 - Gav #
################################################
# - Edit the Variables below and launch the #
# script as an account that can access the #
# machines. #
# - Script will check that logs exist and #
# create them if needed. #
################################################
cls
#VARIABLES - EDIT BELOW
$software = "INSERT SOFTWARE HERE" # - Enter the name as it appears from WMIC query. WMIC PRODUCT NAME
$textfile = "C:\path\pclist.txt"
$Successlogfile = "C:\path\Done_Machines.txt"
$Errorlogfile = "C:\path\Failed_Machines.txt"
#Date Calculation for Logs
$today = Get-Date
$today = $today.ToString("dddd (dd-MMMM-yyyy)")
#Load PC's From Text File
$computers = Get-Content "$textfile"
#Check if Log Files Exist
If (Test-Path $Successlogfile) {
Write-Host -ForegroundColor Green "Success Log File Exists, Results will be appended"
}
else
{
Write-Host -ForegroundColor Red "Success Log File does not exist, creating log file"
New-Item -path $Successlogfile -ItemType file
}
If (Test-Path $Errorlogfile) {
Write-Host -ForegroundColor Green "Error Log File Exists, Results will be appended"
}
else
{
Write-Host -ForegroundColor Red "Error Log File does not exist, creating log file"
New-Item -path $Successlogfile -ItemType file
}
#Run Ping Test and Uninstall if turned on
foreach ($computer in $computers) {
If (Test-Connection -quiet -ErrorAction SilentlyContinue -computername $computer -count 2)
{
Write-Host -ForegroundColor Green "$Computer is responding, Attempting Uninstall of $Software"
Add-Content $Successlogfile "`n$today`n$Computer`n"
Get-WmiObject -class Win32_Product -ComputerName $computer | Where-Object {$_.Name -match $software} | ForEach-Object { $_.Uninstall()}
}
else
{
Write-Host -ForegroundColor Red "$Computer is not responding"
Add-Content $Errorlogfile "`n$today`n$Computer`n"
}
}
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.