I am looking to set "password never expires" for a local Windows user account, for a list of servers in a text file. So far, I found this command line below, but it only works local on single computer. How can I incorporate this into a VBscript, PowerShell, or batch file to apply on a list of servers in a text file?
WMIC USERACCOUNT WHERE "Name='accountname'" SET PasswordExpires=FALSE
This code should do it:
# 1. Define in-line array of servers
$ServerList = #('localhost', 'localhost', 'localhost');
# 2. Define account name
$AccountName = 'test';
# 3. For each server, set the account to expire
foreach ($Server in $ServerList) {
$Account = Get-WmiObject -ComputerName $Server -Class Win32_UserAccount -Filter "Name = '$AccountName'";
$Account.PasswordExpires = $false;
[void] $Account.Put();
}
If you want to import a text file that contains the server names, you can simply change the first line to this:
$ServerList = Get-Content -Path c:\path\to\text\file.txt;
An alternative method would be to use Invoke-Command, however this requires that you first configure PowerShell Remoting in your environment.
# 1. Define in-line array of servers
$ServerList = #('localhost', 'localhost', 'localhost');
# 2. Define the block of code to deploy (a PowerShell ScriptBlock)
$ScriptBlock = {
$AccountName = 'test';
$Account = Get-WmiObject -Class Win32_UserAccount -Filter "Name = '$AccountName'";
$Account.PasswordExpires = $false;
[void] $Account.Put();
};
# 3. Deploy the ScriptBlock to the array of servers
Invoke-Command -ComputerName $ServerList -ScriptBlock $ScriptBlock;
To configure PowerShell Remoting, run the Enable-PSRemoting -Force command on each computer. You can also use Active Directory Group Policy to enable PowerShell Remoting / Windows Remote Management (WinRM).
wmic can be run against remote hosts via the /node parameter:
wmic /node:HostA,HostB useraccount where "Name='accountname'" ...
Related
I'm creating a script that I can use to set up new user account in AD.
Early in the batch file I have a variable that is saved like this -
set state=%pspath% "St" -Value 'Gloucestershire'
pspath is populated later in the batch when the user is actually being created this part -
set pspath="Set-ItemProperty -Path 'CN=%firstname% %lastname%,%ou%' -Name"
powershell -nologo Import-Module ActiveDirectory;Set-Location AD:;%state%;
Firstname, lastname and ou is all populated without a problem, but in that second line when I'm using the %state% variable, %pspath% is ignore and the command comes out as
powershell -nologo Import-Module ActiveDirectory;Set-Location AD:;"St" -Value 'Gloucestershire'
instead of what it should be -
powershell -nologo Import-Module ActiveDirectory;Set-Location AD:;Set-ItemProperty -Path 'CN=%firstname% %lastname%,%ou%' -Name "St" -Value 'Gloucestershire'
How do I get all the variables to populate in the command properly instead of %pspath% being skipped?
On SQL Server 2016 I have setup a job that executes a powershell script that resides on a remote app server. When I execute the powershell script via the app server using the Powershell ISE app my script works without issue. When I had setup the job and enter this command:
powershell.exe -ExecutionPolicy Bypass -file "\\serverapp1\c$\coverageverifier_scripts\SFTP_CoverageVerifier.ps1" in Step 1.
When I look at the VIEW HISTORY I see the error below but I cannot figure out why the script now cannot load the file or assembly.
Any help/direction would be appreciated. Here is the error:
The job script encountered the following errors. These errors did not stop the script: A job step received an error at line 1 in a PowerShell script. The corresponding line is 'powershell.exe -ExecutionPolicy Bypass -File "\empqaapp1\c$\coverageverifier_scripts\SFTP_CoverageVerifier.ps1"'. Correct the script and reschedule the job. The error information returned by PowerShell is: 'Add-Type : Could not load file or assembly '
Here is my powershell script as well:
# Load WinSCP .NET assembly
#Add-Type -Path "WinSCPnet.dll"
Add-Type -Path (Join-Path $PSScriptRoot "WinSCPnet.dll")
# Declare variables
$date = Get-Date
$dateStr = $date.ToString("yyyyMMdd")
# Define $filePath
$filePath = "C:\coverageverifier_scripts\TEST_cvgver.20190121.0101"
# Write-Output $filePath
# Set up session options for VERISK TEST/ACCEPTANCE SFTP SERVER
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::Sftp
HostName = "secureftpa.iso.com"
UserName = "account"
Password = "pw"
SshHostKeyFingerprint = "ssh-rsa 1111 xxx/xxxxxxxxx+3wuWNIkMY5GGgRObJisCPM9c9l7yw="
}
$session = New-Object WinSCP.Session
$session.ExecutablePath = "C:\WinSCP\WinSCP.exe"
try
{
# Connect
$session.Open($sessionOptions)
# Transfer files
$session.PutFiles($filePath,"/").Check()
}
finally
{
$session.Dispose()
Your Add-Type call does not include the path to the WinSCPnet.dll.
If you have the WinSCPnet.dll in the same folder as your PowerShell script, use this syntax:
Add-Type -Path (Join-Path $PSScriptRoot "WinSCPnet.dll")
Or use a full path.
See also Loading assembly section in WinSCP .NET assembly article on Using WinSCP .NET Assembly from PowerShell.
I have file in a folder (ftp_region) whose contents is similar to data in my FTP.
How to download newer files from my FTP and save them to two local folders (ftp_region and other folder)
For now, I use this:
open "my ftp address"
get -neweronly "..." "..."
You cannot do this with a plain WinSCP scripting.
You better use the WinSCP .NET assembly. It allows you to process the downloaded files.
An example code in PowerShell:
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::Ftp
HostName = "ftp.example.com"
UserName = "user"
Password = "password"
}
Write-Host "Connecting..."
$session = New-Object WinSCP.Session
# $session.SessionLogPath = "C:\path\to\log\sync.log"
$session.Open($sessionOptions)
$remotePath = "/remote/path"
$localPathPrimary = "C:\backup\primary"
$localPathSecondary = "C:\backup\secondary"
Write-Host "Synchronizing..."
$result =
$session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, $localPathPrimary, $remotePath,
$False)
$result.Check()
Write-Host "Copying downloaded files to secondary backup..."
foreach ($download in $result.Downloads)
{
$filename = (Split-Path -Leaf $download.Destination)
$localFilePathSecondary = (Join-Path $localPathSecondary $filename)
Copy-Item $download.Destination $localFilePathSecondary
Write-Host "File $filename archived to both folders."
}
The code is based on an official example Deleting remote files after successful remote to local synchronization.
i have a problem that is troubling my mind.
I want to automatically execute powershell scripts with named arguments but within another powershell script (that will act as a script deamon).
For example:
One of the scripts that get called has this parameters
param(
[int]$version,
[string]$user,
[string]$pass,
[string]$domain,
)
The powershell script deamon now loads the file and arguments like this
$argumentsFromScript = [System.IO.File]::ReadAllText("C:\params.txt") $job = Start-Job { & "ps1file" $arguments}
The params.txt contains the data like this
-versionInfo 2012 -user admin -pass admin -domain Workgrup
But when i try to execute this code obviously the whole $argumentsFromScript variable will be seen as parameter 1 (version) and i end up with an error, that "-versionInfo 2012 -user admin -pass admin -domain Workgrup" cannot be converted to Int32...
Do you guys have any idea how i can accomplish this task?
The Powershell deamon does not know anything about the parameters. He just needs to execute scripts with given named parameters. The params.txt is just an example. Any other file (csv,ps1,xml,etc) would be fine, i just want to automatically get the named parameters passed to the script.
Thank you in advance for any help or advice..
Try this:
#'
param ([string]$logname,[int]$newest)
get-eventlog -LogName $logname -Newest $newest
'# | sc c:\testfiles\testscript.ps1
'-logname:application -newest:10' | sc c:\testfiles\params.txt
$script = 'c:\testfiles\testscript.ps1'
$arguments = 'c:\testfiles\params.txt'
$sb = [scriptblock]::Create("$script $(get-content $argumentlist)")
Start-Job -ScriptBlock $sb
I guess you want this:
$ps1 = (Resolve-Path .\YourScript.ps1).ProviderPath
$parms = (Resolve-Path .\YourNamedParameters.txt).ProviderPath
$job = sajb -ScriptBlock {
param($ps1,$parms)
iex "$ps1 $parms"
} -ArgumentList #(
$ps1,
[string](gc $parms)
)
# if you wanna see the outcome
rcjb $job -Wait
Full Question: Have Powershell Script using Invoke SQL command, using snappins, I need them to be included in a SQL job, the SQL Server version of Powershell is somewhat crippled, does anyone know a workaround?
From what I have gathered, SQL Management Studio's version of powershell is underpowered, not allowing for the use of snappins, as such it does not recognize the cmdlets that I used in the script. I have tried running it in the job as a command line prompt rather than a Powershell script, which causes the code to work somewhat, however I check the history on the job and it says that invoke-sql is still not a recognized cmdlet. I speculate that because I am running the code on a remote server, with different credentials than my standard my profile with the snappins preloaded isn't being loaded, though this is somewhat doubtful.
Also, as I am a powershell rookie, any advice on better coding practices/streamlining my code would be much appreciated!
Code is as follows:
# define parameters
param
(
$file = "\\server\folder\file.ps1"
)
"invoke-sqlcmd -query """ | out-file "\\server\folder\file.ps1"
# retrieve set of table objects
$path = invoke-sqlcmd -query "select TableName from table WITH (NoLock)" -database db -server server
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$so = New-Object Microsoft.SqlServer.Management.Smo.ScriptingOptions
$so.DriPrimaryKey = $false
$so.Nocollation = $true
$so.IncludeIfNotExists = $true
$so.NoIdentities = $true
$so.AnsiPadding = $false
# script each table
foreach ($table in $path)
{
#$holder = $table
$table = get-item sqlserver:\sql\server\default\databases\database\tables\dbo.$($table.TableName)
$table.script($so) | out-file -append $file
}
(get-content "\\server\folder\file.ps1") -notmatch "ANSI_NULLS" | out-file "\\server\folder\file.ps1"
(get-content "\\server\folder\file.ps1") -notmatch " AS "| out-file "\\server\folder\file.ps1"
(get-content "\\server\folder\file.ps1") -notmatch "Quoted_" | out-file "\\server\folder\file.ps1"
(get-content "\\server\folder\file.ps1") -replace "\) ON \[PRIMARY\].*", ")" | out-file "\\server\folder\file.ps1"
(get-content "\\server\folder\file.ps1") -replace "\[text\]", "[nvarchar](max)" | out-file "\\server\folder\file.ps1"
(get-content "\\server\folder\file.ps1") -replace " SPARSE ", "" | out-file "\\server\folder\file.ps1"
(get-content "\\server\folder\file.ps1") -replace "COLUMN_SET FOR ALL_SPARSE_COLUMNS", "" | out-file "\\server\folder\file.ps1"
""" -database database -server server" | out-file "\\server\folder\file.ps1" -append
So I figured out the answer to my own question. Using this site: http://www.mssqltips.com/tip.asp?tip=1684 and
http://www.mssqltips.com/tip.asp?tip=1199
I figured out that he was able to do so using a SQL Server Agent Proxy, so I followed the yellow brick road, and basically I set up a proxy to my account and was able to use the external powershell through a feature. A note, you need to create a credential under the securities tab in object explorer prior to being able to select one when creating the proxy. Basically I ended up creating a proxy named powershell, using the powershell subsystem, and use my login info to create a credential. VOILA!
You have to add the snapins each time. In your editor you likely already have them loaded from another script/tab/session. In SQL Server you will need to add something like this to the beginning of the script:
IF ( (Get-PSSnapin -Name sqlserverprovidersnapin100 -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin sqlserverprovidersnapin100
}
IF ( (Get-PSSnapin -Name sqlservercmdletsnapin100 -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin sqlservercmdletsnapin100
}
I'm not sure the error you are trying to workaround - can you post that?
Have you tried this from a PowerShell prompt?
Add-PSSnapin SqlServerCmdletSnapin100