|
Hopefully a double post is okay. Yesterday when doing some work I broke my script, now it tries to install on the local computer multiple times. I fixed it this morning, but I guess I didn't commit those changes like I thought, and then I broke it again. I'm using a foreach to read computer names from a file, and then copy and install files. I've commented out the copying right now because the other computer has the files on it already and that saves time. $computer = "\\$line" $PreReqLoc = "$computer\C$" $ScriptLoc = "$computer\C$\users\public\Documents\scripts" Copy-Item -Path "C:\Scripts" -Destination$computer"\C$\users\public\Documents\" -force -recurse Start-Job { param($location,$PreReqLoc,$ScriptLoc,$accountUsed) #Copy-Item $location -Destination $PreReqLoc -force -recurse write-host $scriptloc Powershell "$ScriptLoc\install.ps1" -executionPolicy bypass #-credential $accountUsed Remove-Item -Path $ScriptLoc -force -recurse} -argumentList $location,$PreReqLoc,$ScriptLoc,$accountUsed Sorry if it's messy, I had to email it from my computer to my phone. When I check the script location variable before the powershell launch, it gives the right computer name, but as soon as it goes into the install script, it's on the local computer. E: well that formatting didn't take, hang on. 22 Eargesplitten fucked around with this message at 19:02 on Jul 14, 2016 |
# ? Jul 14, 2016 18:48 |
|
|
# ? May 13, 2024 21:43 |
|
22 Eargesplitten posted:Hopefully a double post is okay. Yesterday when doing some work I broke my script, now it tries to install on the local computer multiple times. I fixed it this morning, but I guess I didn't commit those changes like I thought, and then I broke it again. First, you may need to escape the $ in the $PreReqLoc and $ScriptLoc by using the backtick (`) character -- so "$computer\C`$" But primarily, the Job is being started with no information. For example, this script connects to a remote computer and gets WMIC info. code:
sloshmonger fucked around with this message at 19:07 on Jul 14, 2016 |
# ? Jul 14, 2016 19:05 |
Which part of your script is actually supposed to invoke the commands to run on the remote machine? That line starting a new Powershell.exe process just starts a process on your own machine. Do your target machines have WinRM enabled? If so, use Invoke-Command (with -AsJob flag) instead of Start-Job to just run PowerShell code directly on each target machine. If your target machine don't have WinRM enabled, or its execution policy doesn't allow remote scripting, you'll have to use some other trickery to get your code to run on it. Either the old psexec utility, or setting up a task scheduler job on it.
|
|
# ? Jul 14, 2016 19:20 |
|
The back tick thing didn't work. Thankfully I was being dumb earlier and the changes were committed, so it's working now. The second script does seem to somehow still be associated with my computer. I used (get-wmiobject win32_operatingsystem).OSArchitecture to get whether the computer is 64 or 32 bit, but it registered as 64 like my computer even when working on a 32-bit. I solved that by passing $computer into the second script and grabbing the architecture from that. Now it's installing all of the x86 programs while the 64-bit machine is installing the x64. -ExecutionPolicy bypass is supposed to temporarily run that script as though the execution policy was set to bypass, right? I've been running everything fine without setting it manually. When I tried to install on the remote computer using a script from my machine Trendmicro blocked it, but running from the remote computer worked fine . Now in place of that powershell line I have code:
Is that difference what's making it work? 22 Eargesplitten fucked around with this message at 20:24 on Jul 14, 2016 |
# ? Jul 14, 2016 20:20 |
You're missing my main point: Nothing in that code ever tells the remote computer to execute anything. You execute PowerShell.exe on your local computer, reading a script from a remote location. The script may be read from a remote location, but it still executes on your local computer. If you want to execute PowerShell code on a remote computer you need to use either Invoke-Command or Import-PSSession, or trickery with New-ScheduledTask or PSExec.
|
|
# ? Jul 14, 2016 20:39 |
|
Huh, weird. When I tried installing from my computer with a locally stored script, it was blocked. I should be able to do an invoke-command within the start-job function, right? That whole thing wouldn't cause a slow copy speed when transferring from a different site's NAS to a computer at the same site, would it? I rewrote it, would this work right? From within the start-job function, where the powershell command was before code:
22 Eargesplitten fucked around with this message at 22:47 on Jul 14, 2016 |
# ? Jul 14, 2016 22:32 |
|
nielsm posted:You're missing my main point: Nothing in that code ever tells the remote computer to execute anything. That won't work for him. Kerberos delegation will break. For him to remotely execute something in invoke-command it takes a delegation. For that remotely executed script to access resources on a file share somewhere it would require a delegation from a delegated position which is a no-go. Either you need to include the secondary script in the main or setup CredSSP.
|
# ? Jul 14, 2016 22:37 |
|
So what I edited in above wouldn't work? Right now the script being executed on my computer has the Copy-Item command, the script I want to execute on their computer is just installation.
|
# ? Jul 14, 2016 23:06 |
|
Nope.code:
Better would be code:
Methanar fucked around with this message at 23:53 on Jul 14, 2016 |
# ? Jul 14, 2016 23:50 |
|
I ended up installing PSExec, but the stuff beneath is still hypothetical if anyone wants to answer it. PSTools seems like it will be really useful. We do have servers on-site, I could transfer the files over and RDP in. Or is even that going to have the same problem? I guess I'm not sure what qualifies as impersonation. And why does the code work on the same subnet as my office, but goes really slow if it works at all on another site's subnet? Maybe that last part is just a sample size of one, the computer seems kind of hosed in general. Is it remoting to the NAS and to the user's computer, but doing it in two different one-hop connections and routing everything through my computer? 22 Eargesplitten fucked around with this message at 17:43 on Jul 15, 2016 |
# ? Jul 15, 2016 16:14 |
Can you use classic Windows remote management with the target machines? E.g. open the Computer Management management console and connect to one of the machines, see its Device Manager etc.? If so, I would suggest something like this: InstallInstaller.ps1 (runs on your computer) code:
code:
Edit: Thinking about it, if you can't establish a CimSession like this, PSExec won't work either, since PSExec also depends on being able to connect to the service control manager of the remote computer to do its job. nielsm fucked around with this message at 19:55 on Jul 15, 2016 |
|
# ? Jul 15, 2016 19:15 |
|
I'm trying it with PSExec, but it's pissing me off more than usual, maybe because it's 4:30 on Friday. I'm doingcode:
I've also tried putting '\\N-AS\b ar\*' directly in where $location is. I had full quotes rather than apostrophes, but I thought there might be a problem with nested quotes. I'm getting an error saying "An object at the specified path \\N-AS\b ar\*" which I think would say cannot be found because it doesn't exist or something if Powershell didn't cut off errors after 80 or so characters. I have cut the path back farther to get rid of the part with the space in case there was something weird there. That PSExec command is inside a Start-Job function, if that might be related. Is there a way to get Powershell to not truncate error messages? And a long shot, show the line errors are on consistently? I got an error saying Missing expression after unary operator -, which isn't very helpful when there's about 20 in a short script.
|
# ? Jul 15, 2016 23:57 |
I'd guess it has to do with escaping there. Try with a simpler command first, like Write-Host, make sure you can get that working. I think you must pass the -Command argument name to PowerShell.exe when giving it something to execute right away: psexec $computer powershell.exe -command { write-host test } There is also the option for -Base64EncodedCommand, which even has an example if you call Powershell.exe -Help. But really, it's probably safer to copy a script file or batch file to the remote and exec that, have the script figure out all its data on its own instead of messing around with escaping.
|
|
# ? Jul 16, 2016 06:45 |
|
22 Eargesplitten posted:I'm trying it with PSExec, but it's pissing me off more than usual, maybe because it's 4:30 on Friday. I'm doing Are you providing PSExec with user credentials? PSExec -? posted:If you omit a user name the process will run in the context of your
|
# ? Jul 16, 2016 06:51 |
That impersonation problem, can that perhaps be related to an issue I was having the other day? I was trying to run a GUI program as another user, using Start-Command -Credential (Get-Credential), loading the program from a network location given by full UNC path. I kept getting file not found errors, loading the program. Passing -LoadUserProfile made no difference. Doing the same thing with classic RunAs.ex works just fine.
|
|
# ? Jul 16, 2016 06:59 |
|
Mo_Steel posted:Are you providing PSExec with user credentials? That and using -command did it. I'm having a hard time finding examples of PSExec statements to read to get an idea of syntax, is there a good site for that?
|
# ? Jul 18, 2016 17:40 |
|
http://ss64.com/ps/ is great for a quick reference.
|
# ? Jul 18, 2016 17:43 |
|
Now when I try to run the script with a PSExec command, it is trying to parse some stuff as cmdlets that it shouldn't. So far it has tried to run the word in as a cmdlet. This is when the command is write-host "In install" It's also trying to parse False as a cmdlet, when the only uses are assigning a boolean variable to $false. When I run just the installation script from the machine I was accessing through PSExec, it works fine.
|
# ? Jul 18, 2016 19:09 |
Why are you trying to PSExec something any more complicated than the name of a batch file?
|
|
# ? Jul 18, 2016 19:22 |
|
I had used it on the last line to copy files from a NAS to a remote computer, so I was thinking about it. It seemed like invoke-command might be easier, but now it's giving me an error saying that one or more computer names isn't valid. I've googled, and I've tried $using:computer instead of $computer, as well as using -args $computer. I've also used the FQDN so $computer is \\computername.contoso.local.code:
|
# ? Jul 18, 2016 21:42 |
If you can Invoke-Command to a remote system, you can just pass plain PowerShell code in a script block without having to wrap it in another call to powershell.exe like that. Invoke-Command uses WinRM to execute PowerShell directly on the target machine, unlike PSExec which installs a temporary service to start an arbitrary process on the target. Also, if you can Invoke-Command on the target machine, you don't really need to change execution policy at all, because you're already executing PowerShell code on the machine at that point. So instead of this: code:
code:
code:
nielsm fucked around with this message at 22:27 on Jul 18, 2016 |
|
# ? Jul 18, 2016 22:21 |
|
That last one works, but I would really prefer not to have to put a 300 line script inside the script block. I've tried doing code:
And all that does is output \install.ps1. I've tried code:
But that gives me an error saying"the argument "\install.ps1" to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.
|
# ? Jul 18, 2016 23:30 |
Invoke-Command can also take a -FilePath argument instead of -ScriptBlock. When you use -FilePath, the path is local and not remote, so you don't have to copy the script over. Do get used to reading the manual pages. They tend to be quite detailed especially for the core commands: https://technet.microsoft.com/library/hh849719.aspx
|
|
# ? Jul 19, 2016 06:05 |
|
Jesus, that did in 2 minutes what I tried and failed to do for half the day yesterday. That also knocks out two lines of code and a variable. I didn't think it would work because Trendmicro prevented me from doing something similar when I first started. I'm sorry if it seems like I'm just coming to the thread as soon as I hit a snag. I have been trying a lot of stuff myself and reading both the technet and ss64 pages, I think I might just be grabbing onto the first thing I see that I think should work either from technet or StackExchange rather than thoroughly understanding every cmdlet I use. Which in hindsight is probably why this has taken weeks rather than an afternoon at most. I also have never used any scripting language before, so I'm trying to figure out the differences between powershell and C++ / Java as I go. Thanks for your patience. 22 Eargesplitten fucked around with this message at 17:04 on Jul 19, 2016 |
# ? Jul 19, 2016 17:00 |
|
While I don't want to go down the depths of "Terminal Ricing" has anyone played around with using Visual Studio, Visual Studio Code or the Powershell ISE and tried to get all of them to use the same color theme? Visual Studio Code - Powershell Extension - The IntelliSense is incredibly fast in VSC but Dark VS Themes don't match VS '15 and there's no actual Interactive Powershell Console. Powershell ISE Dark Theme - I'm using VS 2015 or the author still has the color slightly off... PowerShell Tools for Visual Studio 2015 - Pretty useful but I'm occasionally having some rather strange behavior with various operations. The Interactive Powershell Window is an excellent addition and font amazingly clean.
|
# ? Jul 19, 2016 20:26 |
|
I wrote a script to rename our userPrincipalName and proxyAddresses because we use .local as our tld for everything and we need to move to Office 365. Most of the scripts I found were "just replace the proxyAddresses with 'smtp:samaccountname@domain.tld'!" but a lot of people have alternate email addresses or have changed their last names, so I came up with this monstrosity to just do a find/replace inside of everything instead. I'm probably still reinventing the wheel here, but whatever.code:
ee: also the last creplace should replace uppercase, and add carets and colons to all the replacement strings to make sure it doesn't throw off anything else, like X400 addresses eee: should probably do that with replacing the upn, too anthonypants fucked around with this message at 19:27 on Jul 21, 2016 |
# ? Jul 20, 2016 21:57 |
|
Trying to write a short script to retime subtitles. The function works by itself, but trying to invoke it inside a -replace doesn't work at all. Is there another good method for feeding this data through and doing a mass on-the-fly replace?php:<? $ShiftAmount = -12500 function Shift-TimeCode { Param ([string]$code) Process{ $input = $code [int[]] $timecode = $input.Split(":").Split(",") $rawtimecode = 3600000*$timecode[0] + 60000*$timecode[1] + 1000*$timecode[2] + $timecode[3] $rawtimecode += $ShiftAmount if ($rawtimecode -lt 0) { echo "Error: Shift amount exceeds start time." } $timecode[0] = [int][math]::floor($rawtimecode / 3600000) $rawtimecode -= 3600000*$timecode[0] $timecode[1] = [int][math]::floor($rawtimecode / 60000) $rawtimecode -= 60000*$timecode[1] $timecode[2] = [int][math]::floor($rawtimecode / 1000) $rawtimecode -= 1000*$timecode[2] $timecode[3] = $rawtimecode $output = "$($timecode[0].ToString().PadLeft(2,"0")):$($timecode[1].ToString().PadLeft(2,"0")):$($timecode[2].ToString().PadLeft(2,"0")),$($timecode[3].ToString().PadLeft(3,"0"))" return $output } } $test = "01:02:44,377" -replace "(\d{2}:\d{2}:\d{2},\d{3})", "$(Shift-TimeCode -code $1)"?>
|
# ? Jul 21, 2016 20:07 |
|
I think the problems are 1) unless you use single quotes or a backtick, the $1 will be evaluated too soon, and 2) regardless, I don't think you can delay evaluation of the function until each individual replacement is performed. Unfortunately I guess you can't pass a function to replace like in python. This means that probably you have to do something like: code:
code:
mystes fucked around with this message at 22:53 on Jul 21, 2016 |
# ? Jul 21, 2016 21:11 |
|
The senior tech doesn't want me using WinRM for security reasons, so invoke-command is out. I ended up just copying a batch file over along with the .ps1 to change execution policy, call the script, and then change the policy back. This is what I was thinking of doing in the beginning. I need to stop trying to be clever.
|
# ? Jul 22, 2016 22:14 |
Funny reasoning, because WinRM is far more secure than PSExec. Or are you just copying files over than walking up to each workstation?
|
|
# ? Jul 23, 2016 10:10 |
|
22 Eargesplitten posted:The senior tech doesn't want me using WinRM for security reasons, so invoke-command is out. I ended up just copying a batch file over along with the .ps1 to change execution policy, call the script, and then change the policy back. This is what I was thinking of doing in the beginning. I need to stop trying to be clever. When you call powershell you can do so with the -bypass flag to completely bypass the Execution Policy. Might be easier than trying to futz around with setting then setting back.
|
# ? Jul 25, 2016 14:35 |
|
Argh, I had gotten used to powershell pipes flattening nested lists, but I hadn't realized that any function that returns an actual .net two-dimensional array will flatten it by default unless you stick a comma in front.
|
# ? Jul 27, 2016 04:00 |
|
Zaepho posted:When you call powershell you can do so with the -bypass flag to completely bypass the Execution Policy. Might be easier than trying to futz around with setting then setting back. I thought you couldn't do that while using powershell from the command line/a batch file. I probably did it wrong. Googling suggests no, but is there a way to time out a command? I'm installing an .msu file, but sometimes wusa decides not to work for a half hour +. If not, I'll try shoving all of the .msu installs to the end of the script. Hopefully they aren't required to install any of the other programs.
|
# ? Jul 27, 2016 20:22 |
|
Run it as a job. Then you can use Wait-Job -Timeout
|
# ? Jul 27, 2016 23:24 |
|
Cool, thanks. I guess I could do all of the .msu files in a job so it wouldn't try to run multiple at once.
|
# ? Jul 28, 2016 00:21 |
|
At some point I wrote a quick little script that showed a username, if the user was disabled or not, and then the last logondata, creation date, and last modification date. For the life of me I cant remember it now. Here is my crude rough start at it again, but I cant for the life of me actually get this to pull any data besides someones username. code:
|
# ? Jul 28, 2016 15:36 |
|
code:
|
# ? Jul 28, 2016 16:02 |
Get-ADUser grabs very little data by default. If you need more than the limited default set, use the -Properties parameter to specify what fields you want. Or just use "-Properties *" to get everything.
|
|
# ? Jul 28, 2016 16:02 |
|
nielsm posted:Get-ADUser grabs very little data by default. If you need more than the limited default set, use the -Properties parameter to specify what fields you want. Or just use "-Properties *" to get everything. I think you're on to something. I must've pulled something more specific out of the -properties parameter in the past. I've got text logging enabled in my powershell profile, I'll just have to dig around and find what exactly I was pulling. Methanar posted:
Thanks Methanar! That'll give me a good new base to build off of.
|
# ? Jul 28, 2016 16:07 |
|
|
# ? May 13, 2024 21:43 |
|
Pipe any object to get-member (alias gm) to see all of the different properties and methods you can access on it
|
# ? Jul 28, 2016 20:38 |