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
Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin

Ithaqua posted:

That was going to be my recommendation until I saw "PowerShell 2".

Yeah :(

Adbot
ADBOT LOVES YOU

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
Wait, if I have a 2012 machine, can I make a DSC configuration and push it to client servers that may or may not have the right versions of powershell?

Edit:

Also there's VMware PowerCLI involved too.

Dr. Arbitrary fucked around with this message at 00:54 on Jun 17, 2016

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Dr. Arbitrary posted:

Wait, if I have a 2012 machine, can I make a DSC configuration and push it to client servers that may or may not have the right versions of powershell?

No. All of the machines involved need WMF4 on them.

22 Eargesplitten
Oct 10, 2010



I'm trying to write a script to get files off of a NAS. When I hit the line to copy them over, I get an error saying I don't have permission. I have manually copied files to and from this NAS repeatedly.

code:
Copy-Item -Path $location\foo -Destination C:\

Where $location is the path in the NAS to the folder I'm copying from. Any ideas? I'm wondering if the NAS has its execution policy set to restricted, but I'm not even running it as a script yet.

E: I've already tried running as an administrator, although UAC is off and that seems to make some stuff act weird.

22 Eargesplitten fucked around with this message at 19:43 on Jun 22, 2016

Methanar
Sep 26, 2013

by the sex ghost

22 Eargesplitten posted:

I'm trying to write a script to get files off of a NAS. When I hit the line to copy them over, I get an error saying I don't have permission. I have manually copied files to and from this NAS repeatedly.

code:
Copy-Item -Path $location\foo -Destination C:\
Where $location is the path in the NAS to the folder I'm copying from. Any ideas? I'm wondering if the NAS has its execution policy set to restricted, but I'm not even running it as a script yet.

E: I've already tried running as an administrator, although UAC is off and that seems to make some stuff act weird.

Are you running the script locally, as in not part of an invoke-command statement or something?

Can you post the error?

Toshimo
Aug 23, 2012

He's outta line...

But he's right!
Test-Path $location\foo
Test-Path "$location\foo"

See what you get?

Zaepho
Oct 31, 2013

22 Eargesplitten posted:

I'm trying to write a script to get files off of a NAS. When I hit the line to copy them over, I get an error saying I don't have permission. I have manually copied files to and from this NAS repeatedly.

code:
Copy-Item -Path $location\foo -Destination C:\
Where $location is the path in the NAS to the folder I'm copying from. Any ideas? I'm wondering if the NAS has its execution policy set to restricted, but I'm not even running it as a script yet.

E: I've already tried running as an administrator, although UAC is off and that seems to make some stuff act weird.

Rather than relying on string concatenation (unquoted even) try using (Join-Path $location 'foo') to deal with building a path. This sort of thing has caused me plenty of heartburn in the past. Quick and dirty is great for the command line but awful for any serious production scripts.

Swink
Apr 18, 2006
Left Side <--- Many Whelps
What version are you running? I've had problems with UNC paths with version 3.

My specific problem was trying to invoke commands from a UNC path. The shell just wouldn't see the file.

22 Eargesplitten
Oct 10, 2010



Methanar posted:

Are you running the script locally, as in not part of an invoke-command statement or something?

Can you post the error?

Locally, just running it out of the terminal for now.

I figured it out. For some reason I thought I needed gc to copy the files, so it was telling me I couldn't access the location, but it was still trying to get the files. The problem was Copy-Item wasn't given parameters to merge or overwrite folders that already exist. I also wasn't having it copy subfolders.

This is what happens when someone with no understanding of powershell outside of get-help tries to automate what would otherwise be 100 hours of work.

New error.

code:
$nasName = Read-Host "What NAS do you want to use?"

$location = "\\$nasName\folder\folder"

Copy-Item -Path "$location\folder" -Destination "\\computer\C:\dada" -force

Copy-Item : The given path's format is not supported.

At line:3 char:1

+ Copy-Item -Path "$location\folder" -Destination "\\computer\C:\d ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [Copy-Item], NotSupportedException

    + FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.CopyItemCommand

22 Eargesplitten fucked around with this message at 20:45 on Jun 24, 2016

sloshmonger
Mar 21, 2013

22 Eargesplitten posted:

Locally, just running it out of the terminal for now.

I figured it out. For some reason I thought I needed gc to copy the files, so it was telling me I couldn't access the location, but it was still trying to get the files. The problem was Copy-Item wasn't given parameters to merge or overwrite folders that already exist. I also wasn't having it copy subfolders.

This is what happens when someone with no understanding of powershell outside of get-help tries to automate what would otherwise be 100 hours of work.

New error.

code:
$nasName = Read-Host "What NAS do you want to use?"

$location = "\\$nasName\folder\folder"

Copy-Item -Path "$location\folder" -Destination "\\computer\C:\dada" -force
Copy-Item : The given path's format is not supported.

At line:3 char:1

+ Copy-Item -Path "$location\folder" -Destination "\\computer\C:\d ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [Copy-Item], NotSupportedException

    + FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.CopyItemCommand

Is the destination share "C:"? Maybe it should be \\computer\c$\destinationpath

nielsm
Jun 1, 2009



sloshmonger posted:

Is the destination share "C:"? Maybe it should be \\computer\c$\destinationpath

I don't even think : is a valid character in share names.

22 Eargesplitten
Oct 10, 2010



C$ did it. I didn't realize that wasn't allowed. This is supposed to transfer from a NAS to a user's PC, and it will be followed by sending a .bat and .ps1 to their computer. The .bat will launch the powershell script with a bypassed execution policy, which installs a ton of programs. Or is there a simpler way to do that part?

I'm trying to automate a procedure that takes 2-2.5 hours every time, and I have dozens of computers to do it on. I'll still go on personally to check everything out, but spending ~10 minutes on each to look for errors and maybe do some final configuration is a whole lot better. Thanks for the help, I've been meaning to learn Powershell properly for over a year.

Zaepho
Oct 31, 2013

22 Eargesplitten posted:

Or is there a simpler way to do that part?

I'm trying to automate a procedure that takes 2-2.5 hours every time, and I have dozens of computers to do it on.

SCCM or a similar system is probably the answer you're looking for here.

22 Eargesplitten
Oct 10, 2010



We don't use SCCM. Or PDQDeploy. I'm not joking when I say the current expectation is spending weeks doing this manually. :smithicide:

Methanar
Sep 26, 2013

by the sex ghost

22 Eargesplitten posted:

We don't use SCCM. Or PDQDeploy. I'm not joking when I say the current expectation is spending weeks doing this manually. :smithicide:

How many machines are you responsible for?

22 Eargesplitten
Oct 10, 2010



I'm not sure how many I'll be doing myself, the more senior people will probably be pitching in. But we have about 70 machines total. I've got a laptop I can test this on, at least. That way I'm not under the gun while I fix the inevitable errors.

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

22 Eargesplitten posted:

C$ did it. I didn't realize that wasn't allowed. This is supposed to transfer from a NAS to a user's PC, and it will be followed by sending a .bat and .ps1 to their computer. The .bat will launch the powershell script with a bypassed execution policy, which installs a ton of programs. Or is there a simpler way to do that part?

I'm trying to automate a procedure that takes 2-2.5 hours every time, and I have dozens of computers to do it on. I'll still go on personally to check everything out, but spending ~10 minutes on each to look for errors and maybe do some final configuration is a whole lot better. Thanks for the help, I've been meaning to learn Powershell properly for over a year.

22 Eargesplitten posted:

I'm not sure how many I'll be doing myself, the more senior people will probably be pitching in. But we have about 70 machines total. I've got a laptop I can test this on, at least. That way I'm not under the gun while I fix the inevitable errors.

It's a bit more work to code, but you can build in some switches and error reporting so when something goes wrong it tells you and you can re-run the programs you need more easily. I've been working on something using functions and error checking, so I'll build out a little framework from that as an example.

At the start of your script, you'll need a block like this:

code:
[CmdletBinding()]
Param([Parameter(Mandatory=$False,Position=0)]
      [Switch]$FirstProgram,
      [Parameter(Mandatory=$False,Position=1)]
      [Switch]$SecondProgram,
      [Parameter(Mandatory=$False,Position=2)]
      [Switch]$ThirdProgram
      )
Each parameter is separated by a comma here except for the last one. These will let you call your script like other PS commands (e.g.: .\myScript.ps1 -SecondProgram ) to run specific functions in your program from the main block of code.

Next, define a single variable to catch whether or not any errors happened in this script.

code:
$script:errors = $false
The "script:" portion is for handling scoping, otherwise if you just called it $errors and then in a function also set $errors = $true it won't flag the script-wide variable but rather a function specific one.

Next, you'll need a set of functions to be called by the main part of the script. For example:

code:
function Install-FirstProgram {
    # Install the program
    Start-Process -FilePath "c:\temp\firefox-installer.exe" -ArgumentList "-ms" -Wait

    # Test if the path for the newly installed program exists 
    if (Test-Path "\\path\foo") {
        $script:errors = $true
        return "ERROR: Didn't find \\path\foo "
    }
}
The function runs, calls the installer with arguments if needed, waits until it's done, then checks to make sure the new program was installed to the expected directory, and flags an error state if it didn't (again, I used $script:errors instead of just $errors for scoping reasons). Rinse and repeat for the 2nd and 3rd program installing functions. Once those are setup, we've got to handle the main script that goes below all of your functions and handles the switches:

SIDE NOTE: (There are other ways to test if a program is installed, for example by registry entries to uninstall software, just needed a quick error example)

code:
if ($FirstProgram) {
  Install-FirstProgram
} 
elseif ($SecondProgram) {
  Install-SecondProgram
} 
elseif ($ThirdProgram) {
  Install-ThirdProgram
} 
else {
  Install-FirstProgram
  Install-SecondProgram
  Install-ThirdProgram
}

""
if ($script:errors) { "FAILED: see above for error details" } else { "SUCCESS:  life is good." }
""
If a switch for a specific program is selected, install just that program; otherwise if you just run .\myScript.ps1 it'll install them all. The way it's setup here it'll only run the first of the switches so if you fed it 2 of the 3 switches you'd only get the first one, but you can modify the if/else to ifs if you like and wrap it all in an if / else to check for a no switches state. You can save the logs using Start-Transcript / Stop-Transcript and if they get messy you can always pipe commands to Out-Null to keep it quiet and clean; you can also give it a set of target computers and then dump a foreach loop into the main loop, if you know the targets and they're all available at the same time.

22 Eargesplitten
Oct 10, 2010



Cool, I'll start restructuring it like that. I cut out the .bat file part of the chain. Now I'm just calling the second script that I put on their computer from the first script.

I'm using get-credential to run the second script on my admin account, but I want to verify the credentials because I fat finger the relatively complicated password a lot. How can I check that? I also want to pass those credentials into the second script because SQL server requires them for a command line install. I think I can do that with the arguments parameter in the powershell call.

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

22 Eargesplitten posted:

Cool, I'll start restructuring it like that. I cut out the .bat file part of the chain. Now I'm just calling the second script that I put on their computer from the first script.

I'm using get-credential to run the second script on my admin account, but I want to verify the credentials because I fat finger the relatively complicated password a lot. How can I check that? I also want to pass those credentials into the second script because SQL server requires them for a command line install. I think I can do that with the arguments parameter in the powershell call.

Assuming you're typing the credentials every time, you could try this:

code:
# Used to dump out of the while loop.
$credValid = $false

while (-Not $credValid)
{
    # Store the credentials information you type in.
    $cred = Get-Credential "myDomain\myUsername"

    # Test the credentials by trying to open a new powershell window with them.
    try{
        Start-Process powershell.exe -Credential $cred -ArgumentList “-Verb runAs” -ErrorVariable credError
    } 
    catch { }

    # Check if we captured an error, if so tell the user; if not the credentials are good and we can escape this hellish while loop.
    if ($credError) {
        "Error: Invalid credentials entered."
        $credError = $null
    } 
    else {
        $credValid = $true
    }
}

"Rest of the script"
The only downside is it's going to ask you for valid credentials until you supply it some. Forever. You could code in something to exit after 5 loops and tell you to come back when you aren't drunk. :shrug:

22 Eargesplitten
Oct 10, 2010



Thanks. I'm really learning a lot about powershell in this trial by fire, but sometimes googling doesn't turn much up. This thread is a big help.

Sheep
Jul 24, 2003
Edit: nm, got it to work after much frustration.

Sheep fucked around with this message at 14:18 on Jul 6, 2016

Zaepho
Oct 31, 2013

Sheep posted:

I am bad with Powershell.

code:
$source = 'c:\test'
$dest = 'c:\test2'
$exclude = @("abc","def")
Get-ChildItem $source -Recurse  | where {$_.FullName -notmatch $exclude} | 
    Copy-Item -Destination {Join-Path $dest $_.FullName.Substring($source.length)}
Trying to copy all files/folders under 'test' to 'test2' while excluding directories (and all their children items, obviously) named 'abc' or 'def'. If I do $exclude = 'abc' then it half-works but I obviously get 'def' copied as well. Any ideas?

Life would be easy if Copy-Item respected -Exclude on directories, but nope.
Totally untested but wrap your test in a foreach. Something like the following
code:
$source = 'c:\test'
$dest = 'c:\test2'
$exclude = @("abc","def")
$AllItems = get-childItem -path $source -Recurse

foreach ($item in $AllItems ) {
	$percentcomplete = 0
	if ($allItems.IndexOf($item) -gt 0) {
		$percentcomplete = ($allItems.IndexOf($item) / $allitems.count) * 100
	}
	write-progress -activity "Search in Progress" -status "$($percentcomplete )% Complete:" -percentcomplete $percentcomplete -operation $item.Fullname
	foreach ($ex in $exclude) {
		if ($EX.fullname -match $ex) {
			Write-host "Skipping excluded item $($EX.Fullname)"
			Continue
		}
		copy-item -destination $item.fullname.replace($source, $dest)
	}
}

Sheep
Jul 24, 2003
I wrangled your script into working, thanks!

22 Eargesplitten
Oct 10, 2010



If I call a powershell script from within a powershell script, does the calling script keep going, or does it wait for the second to complete? I want to make mine keep going.

nielsm
Jun 1, 2009



22 Eargesplitten posted:

If I call a powershell script from within a powershell script, does the calling script keep going, or does it wait for the second to complete? I want to make mine keep going.

If you just call it, it runs synchronously. If you want it to be asynchronous, you need to put it inside a Job. Get-Help Start-Job

SeaborneClink
Aug 27, 2010

MAWP... MAWP!
I mistakenly posted this in the Enterprise thread, and received a workable answer but am still hoping for something a little more... clean.

SeaborneClink posted:

What's the most agnostic way to get the path of the Downloads folder?

code:
Get-ChildItem $env:USERPROFILE\Downloads

works on our workstations but not via RDS because we redirect folder to
code:
\\contoso.local\dfs\Users\<user>\
And according to .NET
code:
[Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])
Downloads isn't a recognized Special Folder, yet Templates and CommonOEMLinks are?? :iiam:

So I can't use any form of
code:
[Environment]::GetFolderPath("UserProfile")
because that just returns
code:
C:\Users\<user>
And Desktop isn't a recognized SpecialFolder :suicide:

We have a program that shits files into Downloads and I'm trying to clean up after it, in a simple fashion. :eng99:

Anythonypants (a true hero) offered the below, which does work, but breaks tables. Any other ideas?

anthonypants posted:

Can you look up the registry setting for the path?
code:
(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\" -Name "{374DE290-123F-4565-9164-39C4925E467B}")."{374DE290-123F-4565-9164-39C4925E467B}"

nielsm
Jun 1, 2009



SeaborneClink posted:

I mistakenly posted this in the Enterprise thread, and received a workable answer but am still hoping for something a little more... clean.


Anythonypants (a true hero) offered the below, which does work, but breaks tables. Any other ideas?

The right way is the Known Folders API.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb776911.aspx

On mobile right now so csn't type up an example.


Edit: As far as I can tell, the types for this isn't defined in .NET proper, so you have to declare the related COM interfaces and more to make it work.

nielsm fucked around with this message at 08:00 on Jul 8, 2016

nielsm
Jun 1, 2009



Here's a "PowerShell" way of calling that function to get a known folder path:

code:
Add-Type  @"
using System;
using System.Runtime.InteropServices;

public class KnownFolders
{
    [DllImport("shell32.dll")]
    static extern int SHGetKnownFolderPath(
        [MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
        uint dwFlags,
        IntPtr hToken,
        out IntPtr pszPath  // API uses CoTaskMemAlloc
        );


    public static readonly Guid Desktop = new Guid( "B4BFCC3A-DB2C-424C-B029-7FE99A87C641" );
    public static readonly Guid Documents = new Guid( "FDD39AD0-238F-46AF-ADB4-6C85480369C7" );
    public static readonly Guid Downloads = new Guid( "374DE290-123F-4565-9164-39C4925E467B" );


    public static string GetByGuid(Guid knownfolderid)
    {
        IntPtr pPath;
        int hr = SHGetKnownFolderPath(knownfolderid, 0, IntPtr.Zero, out pPath);
        if (hr == 0)
        {
            string s = Marshal.PtrToStringUni(pPath);
            Marshal.FreeCoTaskMem(pPath);
            return s;
        }
        else
        {
            Marshal.ThrowExceptionForHR(hr);
            return null;
        }
    }
}
"@

[KnownFolders]::GetByGuid([KnownFolders]::Downloads)
There's a more complete list of known folder GUIDs here: http://pinvoke.net/default.aspx/shell32.SHGetKnownFolderPath

nielsm fucked around with this message at 09:25 on Jul 8, 2016

22 Eargesplitten
Oct 10, 2010



How would I make it so the script will start a file transfer on a computer asynchronously and then once that's done, continue by running a second script, but only after the file transfer is done? Would the ScriptBlock parameter for Start-Job do it? Like this?

code:
Start-Job -ScriptBlock {copy foo | Powershell bar.ps1

I'm in the process of uninstalling everything so I can start testing the script again.

nielsm
Jun 1, 2009



More like this:
code:
$jobObject = Start-Job {
    Copy-Item $src $dst
    whatever-script.ps1
}
Or if you don't have a particular reason to have that script as a separate file, you can just put its contents right in the job script block.

22 Eargesplitten
Oct 10, 2010



Okay, thanks. I have to send the script to another computer because if I try to target the remote computer while running the second script from my machine Trendmicro blocks it. It seems to be working now, but I have to wait for the copying to finish to make sure the second script part is working right.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin
Has anyone already written a script that does the following:

Store network settings from existing adapter.
Clear network settings from existing adapter.
Remove adapter in VMware powercli.
Add new adapter in powercli.
Apply old network settings to new adapter.

I'm sure I can figure it out. But if there's already a great script for it, I might save some time and avoid problems.

22 Eargesplitten
Oct 10, 2010



Is there a maximum number of jobs you can have running at once? I'm looking at roughly 70/140 depending on whether copy then install counts as one or two.

Dr. Arbitrary
Mar 15, 2006

Bleak Gremlin

22 Eargesplitten posted:

Is there a maximum number of jobs you can have running at once? I'm looking at roughly 70/140 depending on whether copy then install counts as one or two.

I think it'll keep going until it chokes.

I can only find articles on how to limit it, not how to get around the limit.

Edit:

There might be settings in WSMan that limit memory or processes. But you can change the settings.

slightpirate
Dec 26, 2006
i am the dance commander
I got this to work precisely once, with only one username in the CSV file. If there are more users present, it will Move, Disable, and set the description properly, but doesn't strip out the AD group memberships.
With only one name in the list, it will strip the AD memberships, but complains about 'Domain Users" which is fine. Any ideas on why its not stripping the AD groups from the subsequent users?

code:
Import-Module activedirectory
#variable set
$ConfirmPreference = 'None'

#find users, move them to the disabled OU and disable the account. **SET DATE AND INITIALS IN DESCRIPTION**
$users = Import-Csv -path "C:\powershell\audit\auditprod2.csv" | Foreach {Get-ADUser $_.SamAccountName | Move-ADObject -TargetPath "OU=Disabled_Accounts Pending Deletion,OU=ACCOUNTS,DC=loldomain,DC=com" -PassThru | 
Disable-ADAccount -passthru |
Set-ADUser -server "DCA" -Description "07/13/16 ABC" -passthru |
}
#removes users from AD groups. May warn about primary group (domain users) can ignore for now. Find way to exclude this group in v2.
Get-ADPrincipalGroupMembership -Identity $users | % {Remove-ADPrincipalGroupMembership -Identity $Users -MemberOf $_ -Confirm:$False
 }

nielsm
Jun 1, 2009



Your code is an unreadable mess.
Indent your poo poo properly, and stop making gigantic pipelines when writing scripts you intend to re-use. Gigantic long pipes mainly have use when experimenting on the commandline, and even then storing stuff into variables as intermediate steps makes it much easier to figure out where something might have gone wrong.

Here's a possibly fixed version:
code:
Import-Module activedirectory
#variable set
$ConfirmPreference = 'None'

#find users, move them to the disabled OU and disable the account. **SET DATE AND INITIALS IN DESCRIPTION**
$users = Import-Csv -path "C:\powershell\audit\auditprod2.csv"

$users = $users | Foreach {
  $u = Get-ADUser $_.SamAccountName
  $u = $u | Move-ADObject -TargetPath "OU=Disabled_Accounts Pending Deletion,OU=ACCOUNTS,DC=loldomain,DC=com" -PassThru
  $u = $u | Disable-ADAccount -passthru
  $u = $u | Set-ADUser -server "DCA" -Description "07/13/16 ABC" -passthru

  #removes users from AD groups. May warn about primary group (domain users) can ignore for now. Find way to exclude this group in v2.
  Get-ADPrincipalGroupMembership -Identity $u.distinguishedname | % {
    Remove-ADPrincipalGroupMembership -Identity $Users -MemberOf $_ -Confirm:$False
  }
}
Note that I do the group removal on each individual user, rather than all the users as one.

slightpirate
Dec 26, 2006
i am the dance commander
I'm completely aware my code isn't pretty, but right now I'm working function over fashion. I ran your edited script and it completes, but no changes were made to the memberships regardless of how many users were in the .csv.
The accounts disable, move, and change their description correctly though. I appreciate your tidy coding.

nielsm
Jun 1, 2009



Oh right, made a mistake editing it. The line should be:

Remove-ADPrincipalGroupMembership -Identity $u.distinguishedname -MemberOf $_ -Confirm:$False

slightpirate
Dec 26, 2006
i am the dance commander
You're a gentleman and a scholar! It's working great now. I added the following - it looks like it ignoring "Domain Users" now and isn't issuing a warning.
code:
Get-ADPrincipalGroupMembership -Identity $u.distinguishedname | where {$_.Name -ne "Domain Users"} % {

Adbot
ADBOT LOVES YOU

22 Eargesplitten
Oct 10, 2010



Mo_Steel posted:

Assuming you're typing the credentials every time, you could try this:

code:
# Used to dump out of the while loop.
$credValid = $false

while (-Not $credValid)
{
    # Store the credentials information you type in.
    $cred = Get-Credential "myDomain\myUsername"

    # Test the credentials by trying to open a new powershell window with them.
    try{
        Start-Process powershell.exe -Credential $cred -ArgumentList &#8220;-Verb runAs&#8221; -ErrorVariable credError
    } 
    catch { }

    # Check if we captured an error, if so tell the user; if not the credentials are good and we can escape this hellish while loop.
    if ($credError) {
        "Error: Invalid credentials entered."
        $credError = $null
    } 
    else {
        $credValid = $true
    }
}

"Rest of the script"
The only downside is it's going to ask you for valid credentials until you supply it some. Forever. You could code in something to exit after 5 loops and tell you to come back when you aren't drunk. :shrug:

I used this, but without having it automatically filling in my username, so others can use the script down the line until we get a proper imaging solution. So I just deleted that part from after the get-credential. Now it requires the domain \username rather than just username. Do you know why that is?

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