PowerCLI: Task Automation - powershell

I have a script that I want to make automatically run every Monday and Thursday each week. I was curious how if it is possible to do this on PowerCLI or if I would have to create a .bat to accomplish this goal. I did some searching and learned that this piece of code was necessary in my script at the top of the line:
add-pssnapin VMware.VimAutomation.Core # <----------
$server = $args[0]
$date = get-date
new-snapshot -vm $server -name "Auto Created via Powershell" -description $date
get-snapshot -vm $server | sort -property created -desc | select -skip 6 | foreach-object{remove-snapshot $_ -confirm:$false}
What else would I need to get this code to run every Monday and Thursday?
Thanks!
EDIT: Where would I edit the task scheduler in order to allow this to run? I've provided an image of where I'm at (that and I'm also a visual person :P )

Why not just using the Task Scheduler of Windows to execute your script as:
powershell.exe -file yourscript.ps1
use powershell /? to kown more options

Related

Need to minimize a particular window

I had tried with below script. While using the below command it will minimize all opened applications. I need minimize only the policy updating window only(Gpupdate.exe). please find the attached gpupdate windows screenshots.
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "gpupdate.exe"
Start-Sleep -s 1
$shell = New-Object -ComObject "Shell.Application"
$shell.minimizeall()
Check out Set-WindowState.ps1 at https://gist.github.com/Nora-Ballard/11240204
It utilizes user32.dll ShowWindowAsync function.
After dot sourcing the function, I can use this in a script:
Get-Process -ID $PID | Set-WindowState -State MINIMIZE
Start-Sleep 3
Get-Process -ID $PID | Set-WindowState -State RESTORE
As long as my script is running within its own window this works. You need to have the process that is the window you want to minimize.
When using Windows 11 (and the Windows Terminal), this script may not work properly with using $PID.
To minimize the Windows Terminal, use
(Get-Process | Where-Object {$_.name -Match 'Terminal'}) | Set-WindowState -State MINIMIZE
The problem is, that it minimizes all Windows Terminal windows.

PowerShell script that Changes a computer name based on the current IP address and lookup from a CSV file

We have a large effort underway for specific PC’s (approximately 10,000) that need to be renamed. They are in workgroup mode (not domain joined). Obviously if we can script this and do it remotely we should. I have been trying to better understand PowerShell and think it can actually be done pretty easily if I can get the code right. I need a very simple script that will:
Get the current IP address of the machine.
Compare that IP address to a CSV formatted list.
From the list, use the new Computer Name based on the IP Address and rename the computer.
The CSV would be very simple:
IPADDRESS,NEWCOMPNAME
192.168.0.1,NewPC1
192.168.0.2,NEWPC2
192.168.0.3,NEWPC3
This is the script I have so far but is not working:
$currentIpAddress = Test-Connection $env:COMPUTERNAME -count 1 | select Address, Ipv4Address
$csv = Import-Csv C:\test.csv
$newComputerName = $csv | where {$_.IPADDRESS -eq $currentIpAddress} | % NEWCOMPNAME
Rename-Computer -newname $newComputerName -Force -Restart
Thanks all for your comments and questions. I figured it out. Just to answer the questions and post the correct code for others, here goes. I am hitting Windows 8.1 x64 and Windows 10 x64. Powershell 4 and 5. If the computer name is not in the list, then the script fails (which is good) and does nothing. Also, we are running this as the local admin account, so the tests have proven successful so far.
The updated scripts are:
The CMD we are using:
If Not Exist C:\Temp MD C:\Temp
Copy /Y "%~dp0RenameComputerBasedOnIPList.csv" C:\temp\RenameComputerBasedOnIPList.csv
powershell -ExecutionPolicy ByPass -File "%~dp0RenameComputerBasedOnIPList.ps1"
The PowerShell script that is running:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
$currentIpAddress = Test-Connection $env:COMPUTERNAME -count 1 | select Address, Ipv4Address
$csv = Import-Csv C:\Temp\RenameComputerBasedOnIPList.csv
$newComputerName = $csv | where {$_.IPADDRESS -eq $currentIpAddress.IPV4Address} | % NEWCOMPNAME
Write-Host $currentIpAddress
Write-Host $csv
Write-Host $newComputerName
Rename-Computer -NewName $newComputerName -Force -Restart
The formatted list is like this named RenameComputerBasedOnIPList.csv.
IPADDRESS,NEWCOMPNAME
10.96.21.121,BADCOMPNAME
10.96.21.158,WIN10NAMECHANGE
192.168.0.2,BADCOMPNAME1
10.96.21.52,WIN81NAMECHANGE
Thanks again.

Inactive Computers Script

I wrote a PowerShell script that will check AD for computers that haven't authenticated with it in 30 days. It will then disable the workstations and move them to another OU. It will also create a list and export the CSV file to the C:\Custom Folder. However, I need the script to run as administrator.
$DaysInactive = 30
$time = (Get-Date).Adddays(-($DaysInactive))
Get-ADComputer -Filter {LastLogonTimeStamp -lt $time} -ResultPageSize 2000 -resultSetSize $null -Properties Name, OperatingSystem, SamAccountName, DistinguishedName | Move-ADObject -TargetPath "OU=Inactive,OU=Workstations,DC=genericname,DC=genericname,DC=genericname,DC=genericname" -PassThru |Set-ADComputer -Enabled $False -PassThru |Export-Csv -Path "\\SERVERNAME\c$\IT Documentation\Inactive Computers\inactivecomputers.csv" -NoTypeInformation
I am working on setting the script to run automatically through task scheduler every Friday. How would I need to modify the script to accomplish this?
If I launch PowerShell manually by right clicking and select run as administrator. The script works fine. It's not working through task scheduler though. Any thoughts?
Would I use:
Start-Process powershell -Verb runAs
If so where would I need to insert it?
Good Job. That looks pretty good.
Have a look at these instructions to make a scheduled task out of a script. The short of it is, you open the task scheduler and run powershell.exe with your script in the arguments.
Keep in mind that you will need to run a job that touches AD as yourself, and if you change your password while this job is enabled, it could lock you out by attempting to log in multiple times.

Wait for an Active Directory query to finish before executing next line

Trying to work out how I can make the below code:
Wait for line 1 to complete before continuing.
Wait for line 4 to complete before running line 5
.
$invokevar = Get-ADComputer -Filter * -SearchBase $searchbase | select -Expand dnshostname
New-Variable -name "invoke$dom" -value $invokevar -Force
$fullvar = Get-Variable -Name "invoke$dom" -ValueOnly
$results = Invoke-Command -ComputerName $fullvar -ScriptBlock $sbmain
$badhosts = Compare-Object $($invokevar | Sort-Object) $($results | select -expand pscomputername | Sort-Object) | select -expand InputObject
Having a mental block, any help would be appreciated.
In powershell, the script executes line by line
Unless or until the execution of line 1 finishes, the script wont go for line 2.
So ideally you shouldn't be worrying about the problem stated above.
For internal commands PowerShell does wait before starting the next command. One exception to this rule is external Windows subsystem based EXE applications, you can apply out-null
PowerShell will wait until the exe process has been exited before continuing.
You can also use Start-Process with the -Wait parameter:
Start-Process <path to exe> -NoNewWindow -Wait
If you are using the PowerShell Community Extensions version it is:
$proc = Start-Process <path to exe> -NoWindow
$proc.WaitForExit()
Another option in PowerShell 2.0 is to use a background job:
$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
In your case it will wait for the execution to get completed. Else you can check the status using a do-While loop and keep on adding a start-sleep of 1 sec
Hope this approach helps you.
Those answers are wrong. Get-ADUser absolutely may return data in the middle of the script down the line..
Some get-aduser command
echo "some string"
I have seen output line 2 first and then the results from line 1.
The only way around this is to assign a variable to the query and process the variable.
$string = get-aduser....
process $string
echo "some string"
This will process in order 1,2,3 without failure.

PowerShell Script to query and delete print jobs older than "x" days

I started putting this PowerShell Script together, the hope would be to replace some tasks that are currently carried out manually
I'm using the
get-Date.AddDays()
function
I'm using the ISE to build the script and in testing I get output if I single out the 'starttime' property, but this seems to be a catch all because the values all come up null, ideally I'd like to use the 'timesubmitted' property, but the date seems to output in an odd that I don't think is being read correctly because my queries with 'timesubmitted' always come up empty
it comes out in this format, if you do an open query
20120416030836.778000-420
here's what I have so far.
disregard the | 'format-table' function that's just so I can see if I'm getting the desired output
#Clears Old Print Jobs on Specified server
#Sets Execution Policy for Script to run
Set-ExecutionPolicy RemoteSigned -Force
#establishes variable for cutoff date
$d = Get-Date
$old = $d.AddDays(-4)
#Queries WMI and retrieves print jobs
Get-WmiObject -class win32_printjob -namespace "root\CIMV2" | where-object {$_.timesubmitted -lt
"$old"} | ft caption,document,jobid,jobstatus,owner,timesubmitted
In PowerShell every WMI instance has a ScriptMethod that you can use to convert the dates from WMI format to .NET format:
Get-WmiObject Win32_PrintJob |
Where-Object { $_.ConvertToDateTime($_.TimeSubmitted) -lt $old } |
Foreach-Object { $_.Delete() }
Just an update in case anyone is looking in 2021.
This command/syntax worked for me in 2008 R2 (PowerShell version 2.0) (I was able to piece this together from this page, as well as others).
Finds all jobs over 30 minutes and deletes them:
Get-wmiobject win32_printjob
| Where-Object {[System.Management.ManagementDateTimeConverter]::ToDateTime($_.TimeSubmitted) -lt (Get-Date).addminutes(-30)}
| ForEach-Object { $_.delete() }*