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

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 }

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])

Double-Hop Errors when running Skype for Business Cmdlets

I am attempting to automate the Skype for Business Server installation process in Powershell, I have a script that remotes into specified machines and begins preparing them as Front-End servers. The problem lies when certain SfB cmdlets (SfB commands are all of the form "verb-Cs...", ex. Get-CsUser or Get-CsPool) are run in remote sessions, they throw the double-hop error:
Exception: Active Directory error "-2147016672" occurred while searching for domain controllers in domain...
This is after running Enable-CsComputer, which enables the computer's role-based off its definition in the topology (topology was published successfully). The user object is in all required groups (RTCUniversalServerAdmins, Schema Admins, CsAdministrators & Local Admin rights on all SfB Servers). Oddly enough, the command 'Import-CsConfiguration -localstore" does not throw errors, and it's in the same remote session. There may be other local or domain groups that I need to be in, but I cannot pinpoint exactly which and have not seen them documented in the Skype build guides. Skype commands that have parameters to specify targets or just pull data, such as Get-CsPool or Get-CsAdForest, do not have errors because they are run in the local scope. The Enable-CsComputer has no parameter for the computer name, it has to be executed from that machine itself.
Enabling CredSSP delegation on each server is not an option, and I'm not understanding why there is a "second hop" in this command! If the second hop was a resource on a file server or database, that would make sense, and be easy to solve, but in this case, I can't track it. Can anyone tell me what I may be missing?
Here's a code sample to try and illustrate. From the jumbox I get the pool data to create an array, and a session is opened to each machine:
$ServerArray =get-cspool -identity $poolName
$i=0
$SessionArray = #{}
foreach($server in $ServerArray.Computers){$SessionArray[$i] = new-PsSession -ComputerName $server}
foreach($session in $SessionArray.values){
invoke-Command -session $session -scriptBlock {
#remote commands:
import-csConfiguration -<config file path> -localstore; #no errors
enable-CsReplica; #no errors
enable-cscomputer; #double hop error here
}}
If I log into that machine and run the same command, it executes fine but the intention of the project is to automate it on an arbitrary number of machines.
It looks like it's just trying to authenticate to a domain controller, which is reasonable. You'll have to approach this like any other double-hop issue.
Microsoft has an article dedicated to the double hop issue, and has a few solutions other than CredSSP that you can look at: Making the second hop in PowerShell Remoting

Powershell invoke-command multihopping

I have a question regarding multihopping in a windows environment.
Let's say I have a schedule running on Server A (Central Scheduler) which executes a command on Server B. This script contains a call to save files on a remote filer (UNC path, Server C). Hop 1 (from A to B) works well, hop 2 (from B to C) fails.
I already tested to save the files locally on server B, that works flawlessly.
I think there's a problem with the second hop. I remember reading something like this on a forum a while ago, but can't remember a solution.
In detail, the command looks like this:
$session = New-PSSession -computer ComputerName
$templatepath = "\\filerpath\"
Invoke-Command -Session $session -Scriptblock { powershell ovpmutil cfg pol dnl $Using:templatepath /p \BSH }
To clarify: Powershell gives me an "Access denied" when performing the second hop. I already enabled Credential delegation as described here:
Enabling Multihop Remoting
Any help is appreciated. Thanks in advance
The solution is a real pain in the backside if you ask me but here it is...
On the originating server (A):
Set-Item WSMAN:\localhost\client\auth\credssp -value $true
On the intermediate server (B):
Set-Item WSMAN:\localhost\client\auth\credssp -value $true
Open Group Policy editor on server A, navigate to:
Computer Configuration > Administrative Templates > System > Credentials Delegation
Enable these options:
Allow delegating fresh credentials
Allow delegating fresh credentials with NTLM-only server authentication
Both policies need to have server B added to the allowed list, wildcards are allowed. Note that if you use RDP from server A you'll also need to add TERMSRV/*
When running Invoke-Command from server A, include the -Authentication CredSSP param.
Note that if saving SecureStrings somewhere for the credential to connect to server C, you'll want to either use a fixed encryption (specify byte array) or plain text and convert it.

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

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.

How to remotely register static ETW manifests as part of a website deployment?

I'm doing a pilot effort to use the new EventSource (Microsoft.Diagnostics.Tracing.EventSource from nuget) and its new support for ETW channels in order to write to the windows event log. The code is in place, and it writes properly to my workstations event log. I'm thrilled.
Now comes the difficult part. The application that's taking advantage of this capability is a web service, and we deploy it with webdeploy as part of a build-deploy-test system. Because usage of ETW channels requires static registration of provider manifests via wevtutil.exe. The EventSource documentation states that this is best done as part of an installer, but this seems a bit out of webdeploy's capabilities.
Our aim is that we would be able to automatically uninstall the manifest resident on the target server immediately before executing the webdeploy package, and then to import the new manifest after the webdeploy sync has completed. We're not set on this, but it seems like the most sensible way.
For that reason, it seems like maybe this is something that powershell remoting might be able to solve, but it's not an area I know much about.
Has anyone done something like this? Is there a better or simpler way?
There are only a few requirements here. A) the remote machine must have PowerShell remoting enable which also means it must have PowerShell 2.0 or higher B) the script running on the local machine must be able to run as administrator and the credentials used must have admin privileges on the remote machine. If you can meet those requirements then this should be cake.
On the remote machine you need to execute two commands to enable remoting:
Set-ExecutionPolicy RemoteSigned
Enable-PSRemoting -Force
Then on the local machine from an elevated prompt you should be able to execute something like this from a script:
# these two paths assume these files have been copied to the remote computer and to a directory
# in which the service account has privileges to read i.e. not under a userprofile dir.
$etwDllPath = c:\somepath\myassembly.mysourcename.etwManifest.dll
$etwManPath = c:\somepath\myassembly.mysourcename.etwManifest.man
$s = New-PSSession -ComputerName <remoteComputerName>
Invoke-Command -Session $s {param($man) wevtutil.exe um $man} -arg $etwManPath
Invoke-Command -Session $s {param($man,$dll) wevutil.exe im $man /rf:$dll /mf:$dll} -arg $etwManPath, $etwDllPath
Remove-PSSession $s
If you can avoid a remote path with spaces, try to. It will make this easier. :-)