Script to get Windows 7 backup status of multiple client computers and send email if one fails - powershell

I have looked around and not found anything about remotely checking Windows 7 backup status.
We have Windows 2008 R2 SBS running our domain with 5 Windows 7 client computers. Each client computer is backing up to a NAS (some programs we have are a huge pain to re-install if a hard drive dies, so we have a system image of each). I would like to run a PowerShell script that checks each client computer for a successful backup and if one has failed, send an email.
What I need help with the most is the part to query each computer for backup status.

There are so many way you can approach this problem. Here is one way:
You can schedule a job on each computer that runs a script which checks the status code of the backup job and if it detects failure send an email.
Now? How do you get the task results? You might use something like this (not tested)
$s = New-Object -com Schedule.Service
$s.connect
$au = $s.getfolder('').gettasks(0) | where {$_.name -match 'automaticbackup'}
if ( $au.LastTaskResult -ne 0) {
##send email
}
Depending on the version of the PowerShell you can, for example, use 'send-email' cmdlet.
Hope this helps get you started.

Related

WOL works outside of Powershell

Regardless of what Script I use I can not get PowerShell 5.1 to trigger a boot on my Hyper-V Host.
I can use the solarwinds WakeonLan tool to boot the server, but I would like to find a solution that would work natively.
I tried many scripts I had found online and as a last ditch effort, I installed the "WakeOnLAN 1.0" Module but while it says it executes successfully the server does not boot
PS C:\WINDOWS\system32> Invoke-WakeOnLan 52:a4:4c:52:d7:52 -Verbose
VERBOSE: Wake-on-Lan Packet sent to 52:a4:4c:52:d7:52
What could cause the server only to boot with the SolarWinds WakeOnLan.exe but not natively in Powershell?
As it may be relevant the computer I am attempting to send the MagicPacket from is a MultiNic Machine but only 1 NIC is IP'd on the subnet of the Hyper-V server.
Other Scripts I attempted to use:
https://www.pdq.com/blog/wake-on-lan-wol-magic-packet-powershell/
https://powershell.one/code/11.html
Something like this works for me with remote powershell, going to the same subnet the down computers are on. Fast startup also has to be disabled in the windows 10 registry (HiberbootEnabled=0).
$mac = #{comp002 = '00:11:22:33:44:55'; comp003 = '00:11:22:33:44:56'}
$compsDown = 'comp002','comp003'
# (,) is silly workaround to pass array as invoke-command arguments
icm comp001 invoke-wakeonlan.ps1 -args (,$mac[$compsDown])

PowerShell - showing a message on remote computer screen

When I am running commands or installing software remotely using PowerShell - Invoke-Command etc I would like sometimes to be able to show a message on the remote screen so the user knows something is happening, or when work done etc.
I would like to if possible make this message look as professional as possible, e.g. better than just a standard winform message box if it can be done? perhaps more the style of the Windows 10 ones with coloured background and use of image if possible.
Spent a while googling but most seem to relate to using obsolete methods such as net-send or using msg.exe.
Thanks
https://michlstechblog.info/blog/powershell-show-a-messagebox/
So the issue really isnt creating the messagebox itself, its having it show on the users session.
So when you run a command against a system, youre using your creds to run the command therefore it wont show in the users session. You can get around this by running it in the users context using a task scheduler. I have a script that does all this for you but, id hate to recreate the wheel and will have to wait till monday (when im at work) to post it here.
It accepts user input in your sessions that outputs it to a vbs, which then copies it over the message to the users machine, and a task schedule is set to run immediately for the user thats logged in.
edit: The script is this without the task scheduler. I just invoke gwmi win32_computersystem | Select -ExpandProperty username to get the current user logged in and add it to the task.
#Prompt for messge
$strMSG = Read-Host -Prompt "Enter message"
#deleting vbs if it exists
del C:\brief\test.vbs
#creating vbs from scratch so it doesnt override
New-Item C:\brief\test.vbs
#Appending each the values to a seperate line
Add-Content C:\brief\test.vbs 'Set objShell = Wscript.CreateObject("WScript.Shell")'
Add-Content C:\brief\test.vbs "strText = `"$strMSG`""
Add-Content C:\brief\test.vbs 'intButton = objShell.Popup(strText,0,"Computer Support",48)'
#calling on the script
& cscript C:\brief\test.vbs
Found a great solution here which appears on quick testing to work well for displaying a toast notification on a remote machine
https://smsagent.blog/2019/06/11/just-for-fun-send-a-remote-toast-notification/

Start-Process, set focus (?) and press key on virtual machine disconnected from RDP

I have a situation which I need some help with.
I'm running an Azure build pipeline on microsoft hosted private VM with quite a old build program/IDE which does not have any CLI.
So I have to start the program and then press a key (F10) to start the build, right now i'm using Powershell for this.
I have issues though to get this to work on the VM when I have disconnected RDP, almost always (not 100%) when I have rdp open my script works and set focus to the program and presses the key. But sometimes it doesn´t work, and it seems to always fail when the rdp is disconnected. My build fails and when I connect with RDP the window is just grey:d out and it hasn't registered any keypress.
I have found some similar threads which seems to touch upon the issue, but not any solution for Powershell.
Setting focus to window in a virtual machine
Sendkeys On Disconnected RDP Session
One solution seems to be to redirect standard input to the started program which means we don't have to care about focusing the window, but how do I redirect a keypress to a started process with Powershell? (Any other scripting language available in azure pipelines yaml is also ok)
The best solution so far has been
param
(
[string]$appName,
[string]$key
)
$objShell = New-Object -ComObject wscript.shell
$proc = Get-Process $appName
$objShell.AppActivate($proc.Id)
Start-Sleep -Seconds 1
$keyString = "'{" + $key + "}'"
$objShell.SendKeys($keyString)
But as stated, this seems to only work when I have an active RDP connection (and not 100% of the time). I have also tried using SetForegroundWindow which works fine when I run the script on my own computer but not on the VM.
Many thanks
Carl

Can you use a powershell script to create a powershell script?

So this may be an odd request and maybe I'm going about this all wrong but I also have a unique situation. I have servers that are sometimes cloned and I need to run a script that I created on the clones servers. Due to the nature of the clones they cannot be connected to a network.
Currently I am manually putting the generic script on each server before cloning and then running the script on the clone server.
What I would like to do is have a script that runs and gathers all the information, say installed programs as an example, and generate a custom version of my current script on the servers before they are cloned.
I have both the powershell script that gets the server information and the generic one that makes the changes to the clone but I have not found a way to merge the two or any documentation so I don't know if i am hitting a limitation with this one.
Edit for more explanation and examples. I'm doing this from my phone atm so I dont have an example I can post.
Current I have a script that has a set number of applications to uninstall, registry keys to remove, services to stop ect. In another application I have a list of all the software that we have for each server and I can pull that data for each server. What I need to do is pull the data for each server, and have a script placed on each server that will uninstall just the programs for that server.
Currently the script has to run through every potential software and try to uninstall it and then check the other application to see if there are any additional programs that need to be uninstalled.
Hope this extra info helps.
Thanks.
Stop thinking of it as code.
Use script 1 to export blocks of text into a new file. for example, you might have a configuration that says all Dell servers must have this line of code run:
Set-DELL -attribute1 unmanaged
where on HP, the script would have been
Set-HP -attribute1 unmanaged
on web servers, you want:
set-web -active yes
where if not a web server, you want nothing.. so, your parent script code would look like:
$Dell = "Set-DELL -attribute1 unmanaged"
$HP = "Set-HP -attribute1 unmanaged"
$web = "set-web -active yes"
if (Get-servermake -eq "Dell")
{
$dell | out-file Child.ps1 -append
}
if (Get-servermake -eq "HP")
{
$HP | out-file Child.ps1 -append
}
if (Get-webserver -eq $true)
{
$web | out-file Child.ps1 -append
}
The result is a customized script for the specific server, child.ps1.
Now, you can take this and run with it. You could say add functionality to the child script like "Is it an AD controller", etc.
However, you might be better off having all of this in a single script, and just block off sections that don't apply in an if statement for example.
I'm still not totally sure I understand what your asking. If I've missed the mark, tell me how, and I'll tell you how to tweak this better. (And hopefully obvious is that the Get-whatever is sample code. I don't expect that to be what your using to determine a computer make/model/etc)

Can I tell Powershell remote session to deploy from server a to b and from b to c

We have a TeamCity machine.
We have a networkshare.
We have "client" server A
We have "target" server B.
The TeamCity machine need to grab a already existing .zip file from the networkshare and move it to server A which again has to forward it to server B.
There is no direct access from teamcity machine to server B. Server A is always the gateway/bridge I have to take.
What is the best approach here to fullfill my task using powershell?
I have already a working version using a powershell filewatcher on server A watching file dumps and moving those files to server B.
I want a technical more sophisticated solution.
I am not sure what you mean by "I want a technical more sophisticated solution." but based on your description, the following script will do what you require:
$NetworkSourcePath = "\\Network\Path\To\Source.zip"
$ServerA_Destination = "\\ServerA\C$\Path\To\ServerA_Destination.zip"
$ServerB_Destination = "\\ServerB\C$\Path\To\ServerB_Destination.zip"
Copy-Item $NetworkSourcePath $ServerA_Destination
Invoke-Command -ComputerName A -ArgumentList $ServerA_Destination,$ServerB_Destination -ScriptBlock { Copy-Item $ServerA_Destination $ServerB_Destination }