Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
22 Eargesplitten
Oct 10, 2010



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

Adbot
ADBOT LOVES YOU

sloshmonger
Mar 21, 2013

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.

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.


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:
Start-Job -ArgumentList ($Address,$ADCredential) -ScriptBlock {
            param($add,$cred)
            $RemoteHost = ([System.Net.DNS]::GetHostByAddress($add)).HostName
            $os = Get-WmiObject -Class win32_OperatingSystem -Credential $cred -ComputerName $RemoteHost
            $sys = Get-WmiObject -Class win32_ComputerSystemProduct -Credential $cred -ComputerName $RemoteHost
            $mem = Get-WmiObject -Class win32_PhysicalMemory -Credential $cred -ComputerName $RemoteHost
            $comp = Get-WmiObject -Class win32_ComputerSystem -Credential $cred -ComputerName $RemoteHost
           #Do a bunch of stuff here
            return $HostInfo
        } 
Edit: Crap, I should really read to the end. You've got -ArgumentList tacked on there. Maybe it's the backtick thing

sloshmonger fucked around with this message at 19:07 on Jul 14, 2016

nielsm
Jun 1, 2009



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.

22 Eargesplitten
Oct 10, 2010



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:

Powershell -ExecutionPolicy bypass -File "$Scriptloc\install.ps1" -credential $accountUsed -argumentlist $computer.

Is that difference what's making it work?

22 Eargesplitten fucked around with this message at 20:24 on Jul 14, 2016

nielsm
Jun 1, 2009



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.

22 Eargesplitten
Oct 10, 2010



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:

Icm -cn $computer -ScriptBlock {Set-Executionpolicy bypass
Icm -cn $computer -Filepath "$Scriptloc\install.ps1" -credential $accountUsed
Icm -cn $computer -ScriptBlock {Set-Executionpolicy restricted}

22 Eargesplitten fucked around with this message at 22:47 on Jul 14, 2016

Methanar
Sep 26, 2013

by the sex ghost

nielsm posted:

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.

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.

22 Eargesplitten
Oct 10, 2010



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.

Methanar
Sep 26, 2013

by the sex ghost
Nope.

code:
Icm -cn $computer -Filepath "$Scriptloc\install.ps1" -credential $accountUsed
The invoke-command takes your first hop and calling a remote file location would take a second hop. For more info read about the two hop problem.

Better would be

code:
 Icm -cn $computer -scriptblock {

echo "hello"

} >> log.txt

Or you could use CredSSP (which is a work-around for the kerberos two hop problem), use PSexec (which is not invoke-command) or set the secondary script as a shutdown script and reboot everything at 1 am on a saturday.

Methanar fucked around with this message at 23:53 on Jul 14, 2016

22 Eargesplitten
Oct 10, 2010



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

nielsm
Jun 1, 2009



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:
$targets = import-csv "computers.csv"
$MyScriptsFolder = "C:\MyScripts\"
$PerformInstallScriptName = "PerformInstall.ps1"

$targets | foreach-object {
    $TargetShare = "\\$($_.computername)\C`$\Temp\"
    Copy-Item "$MyScriptsFolder$PerformInstallScriptName" "$TargetShare$PerformInstallScriptName"

    $cimsession = New-CimSession $_.computername
    $TaskAction = New-ScheduledTaskAction "PowerShell.exe" "-executionpolicy bypass -noprofile -noninteractive -file `"C:\Temp\$PerformInstallScriptNAme`"" -CimSession $cimsession
    $TaskTrigger = New-ScheduledTaskTrigger -at (Get-Date).AddMinutes(1) -randomdelay (New-TimeSpan -minutes 10) -once -CimSession $cimsession
    New-ScheduledTask -Action @($TaskAction) -Trigger @($TaskTrigger) -CimSession $cimsession
    Remove-CimSession $cimsession
}
PerformInstall.ps1 (runs on target computer)
code:
$InstallerSource = "\\server\share\MyApp"
$InstallerDest = "C:\Temp\MyAppInstaller\"
Copy-Item $InstallerSource $InstallerDest -Recurse

$($InstallerDest)\setup.exe -silent
This is completely untested, but it's how I would think it can be done, without relying on psexec. The PerformInstall script should run as your user on the target machine, since you created the scheduled task. You should be able to change that by passing extra credentials around, possibly also creating the CimSession as the other user.


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

22 Eargesplitten
Oct 10, 2010



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

code:

$Computer = "\\foo"
$PreReqLoc = "$Computer\C`$"
$location = '\\N-AS\b ar\*'

PSExec $computer powershell "Copy-Item $location $PreReqLoc"

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.

nielsm
Jun 1, 2009



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.

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

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

code:
$Computer = "\\foo"
$PreReqLoc = "$Computer\C`$"
$location = '\\N-AS\b ar\*'

PSExec $computer powershell "Copy-Item $location $PreReqLoc"
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.

Are you providing PSExec with user credentials?

PSExec -? posted:

If you omit a user name the process will run in the context of your
account on the remote system, but will not have access to network
resources (because it is impersonating). Specify a valid user name
in the Domain\User syntax if the remote process requires access
to network resources
or to run in a different account. Note that
the password and command is encrypted in transit to the remote system.

nielsm
Jun 1, 2009



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.

22 Eargesplitten
Oct 10, 2010



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?

Video Nasty
Jun 17, 2003

http://ss64.com/ps/ is great for a quick reference.

22 Eargesplitten
Oct 10, 2010



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.

nielsm
Jun 1, 2009



Why are you trying to PSExec something any more complicated than the name of a batch file?

22 Eargesplitten
Oct 10, 2010



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:

Invoke-command -cn $computer -Credential $accountUsed -ScriptBlock {Powershell $scriptLoc -ExecutionPolicy bypass} -argumentlist $computer $scriptLoc, $preReqLoc

nielsm
Jun 1, 2009



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:
Invoke-Command -cn $computer -scriptblock { powershell -executionpolicy bypass -file myscript.ps1 }
or even this:
code:
Invoke-Command -cn $computer -scriptblock {
    set-executionpolicy bypass -scope process -force
    myscript.ps1
}
just do this:
code:
Invoke-Command -cn $computer -scriptblock {
    # paste contents of myscript.ps1 here
}

nielsm fucked around with this message at 22:27 on Jul 18, 2016

22 Eargesplitten
Oct 10, 2010



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:
 Invoke-command -cn $computer -ScriptBlock {"ScriptLoc\install.ps1"}

And all that does is output \install.ps1. I've tried

code:
 Invoke-command -cn $computer -ScriptBlock {powershell -File "ScriptLoc\install.ps1"}

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.

nielsm
Jun 1, 2009



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

22 Eargesplitten
Oct 10, 2010



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

Gucci Loafers
May 20, 2006

Ask yourself, do you really want to talk to pair of really nice gaudy shoes?


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.

anthonypants
May 6, 2007

by Nyc_Tattoo
Dinosaur Gum
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:
$ou = "OU=Organizational Unit,DC=domain,DC=tld"
foreach ($u in Get-ADUser -SearchBase $ou -Filter * -Properties userPrincipalName,proxyAddresses | Where-Object {$_.proxyAddresses[0] -ne $null}) {
    $upn = $u.userPrincipalName -replace "local","net"
    Set-ADUser $u -UserPrincipalName $upn
    $prx = $null
    foreach ($p in Get-ADUser $u -Properties proxyAddresses | Select-Object -ExpandProperty proxyAddresses) {
        $p = $p -replace ".local$",".net"
        if (($p -clike "smtp:*") -and ($p -like "*$($u.SamAccountName)*net")) {
            $p = $p -replace '^smtp:','SMTP:'
        } else {
            $p = $p -creplace '^SMTP:','smtp:'
        }
        if ($prx -notcontains $p) {
            $prx += @($p)
        }
    }
    Set-ADUser $u -Replace @{proxyAddresses=$prx}
}
e: sometimes the samaccountname or the proxyaddresses don't have matching upper/lowercase so it can't be in the -clike statement or else nothing gets
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

Toshimo
Aug 23, 2012

He's outta line...

But he's right!
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)"?>

mystes
May 31, 2006

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:
foreach ($line in $input_text -split  '[\r\n]') {
if ($line -match "(\d{2}:\d{2}:\d{2},\d{3})" ) {
$line = $line -replace "(\d{2}:\d{2}:\d{2},\d{3})",(Shift-TimeCode -code $Matches[1])
}
$line
}
Edit: Actually, better idea: just use a .net regex directly. This way you can pass a script block as a MatchEvaluator delegate:
code:
$r = [regex] "(\d{2}:\d{2}:\d{2},\d{3})"
$r.Replace("01:02:44,377", ${function:Shift-Timecode})
Why is everything in powershell half-baked like this? It always seems nice but then by the time you fix the wrinkles you end up writing what's essentially c#.

mystes fucked around with this message at 22:53 on Jul 21, 2016

22 Eargesplitten
Oct 10, 2010



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.

nielsm
Jun 1, 2009



Funny reasoning, because WinRM is far more secure than PSExec. Or are you just copying files over than walking up to each workstation?

Zaepho
Oct 31, 2013

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.

mystes
May 31, 2006

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.

22 Eargesplitten
Oct 10, 2010



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.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
Run it as a job. Then you can use Wait-Job -Timeout

22 Eargesplitten
Oct 10, 2010



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.

BaseballPCHiker
Jan 16, 2006

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:
Import-Module ActiveDirectory
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –Properties "DisplayName", "msDS-UserPasswordExpiryTimeComputed" | Select-Object -Property "Displayname", "lastlogontimestamp", "lastlogon"
What stupid obvious thing am I missing?

Methanar
Sep 26, 2013

by the sex ghost
code:
 Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –Properties "DisplayName", "msDS-UserPasswordExpiryTimeComputed", "lastlogondate", "whencreated", "modified" `
|  ft samaccountname, lastlogondate, whencreated, modified, msds-userpasswordexpirytimecomputed -AutoSize
What about something like this?

nielsm
Jun 1, 2009



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.

BaseballPCHiker
Jan 16, 2006

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:

code:
 Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} &#150;Properties "DisplayName", "msDS-UserPasswordExpiryTimeComputed", "lastlogondate", "whencreated", "modified" `
|  ft samaccountname, lastlogondate, whencreated, modified, msds-userpasswordexpirytimecomputed -AutoSize
What about something like this?

Thanks Methanar! That'll give me a good new base to build off of.

Adbot
ADBOT LOVES YOU

Roargasm
Oct 21, 2010

Hate to sound sleazy
But tease me
I don't want it if it's that easy
Pipe any object to get-member (alias gm) to see all of the different properties and methods you can access on it

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply