PowerShell :: SQL SELECT returns only first row - sql-server

I have a strange feeling I'm doing something wrong here.
This is my PowerShell script, of course stolen and adapted from here:
param(
$instance = "localhost"
)
if (!(Get-Module -ListAvailable -Name "SQLPS")) {
Write-Host -BackgroundColor Red -ForegroundColor White "Module Invoke-Sqlcmd is not loaded"
exit
}
#Function to execute queries (depending on if the user will be using specific credentials or not)
function Execute-Query([string]$query,[string]$database,[string]$instance,[int]$trusted,[string]$username,[string]$password){
if($trusted -eq 1){
try{
Invoke-Sqlcmd -Query $query -Database $database -ServerInstance $instance -ErrorAction Stop -ConnectionTimeout 5 -QueryTimeout 0
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
}
else{
try{
Invoke-Sqlcmd -Query $query -Database $database -ServerInstance $instance -Username $username -Password $password -ErrorAction Stop -ConnectionTimeout 5 -QueryTimeout 0
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
}
}
function List-of-Databases([string]$instance,[int]$trusted,[string]$login,[string]$password){
$ctpQuery = "
SELECT name
FROM master.dbo.sysdatabases
"
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)[0]
}
function Check-SysAdminLogins([string]$instance,[int]$trusted,[string]$login,[string]$password){
$sysadminLoginsQuery = "
SELECT name
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name
"
return $(Execute-Query $sysadminLoginsQuery "master" $instance $trusted $login $password)
}
$loginChoices = [System.Management.Automation.Host.ChoiceDescription[]] #("&Trusted", "&Windows Login", "&SQL Login")
$loginChoice = $host.UI.PromptForChoice('', 'Choose login type for instance', $loginChoices, 0)
switch($loginChoice)
{
1 {
$login = Read-Host -Prompt "Enter Windows Login"
$securePassword = Read-Host -Prompt "Enter Password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
}
2 {
$login = Read-Host -Prompt "Enter SQL Login"
$securePassword = Read-Host -Prompt "Enter Password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword))
}
}
#Attempt to connect to the SQL Server instance using the information provided by the user
try{
switch($loginChoice){
0 {$buildNumber = Execute-Query "SELECT 1" "master" $instance 1 "" ""}
default {$buildNumber = Execute-Query "SELECT 1" "master" $instance 0 $login $password}
}
}
catch{
Write-Host -BackgroundColor Red -ForegroundColor White $_
exit
}
#If the connection succeeds, then proceed with the verification of best practices
Write-Host ""
Write-Host "------------ ------------ ------------ ------------"
Write-Host "************ ************ ************ ************"
Write-Host "------------ ---- ---- ------------"
Write-Host " **** ************ ************ **** "
Write-Host " ---- ------------ ------------ ---- "
Write-Host " **** **** ***** **** "
Write-Host " ---- ------------ ------------ ---- "
Write-Host " **** ************ ************ **** "
Write-Host ""
#List of Databases
Write-Host "#####################"
Write-Host "# List of Databases #"
Write-Host "#####################"
switch($loginChoice){
0 {$lod = List-of-Databases $instance 1 "" ""}
default {$lod = List-of-Databases $instance 0 $login $password}
}
foreach($database in $lod)
{
Write-Host $database.name | Format-Table
}
Write-Host ""
#Logins with sysadmin privilege
Write-Host "##################################"
Write-Host "# Logins with sysadmin privilege #"
Write-Host "##################################"
switch($loginChoice){
0 {$sysadminLogins = Check-SysadminLogins $instance 1 "" ""}
default {$sysadminLogins = Check-SysadminLogins $instance 0 $login $password}
}
foreach($sysadminLogin in $sysadminLogins)
{
Write-Host $sysadminLogin.name
}
Write-Host ""
If you run it the scripts gets executed successfully :
The problem is that the second query:
SELECT name
FROM master.sys.server_principals
WHERE IS_SRVROLEMEMBER ('sysadmin',name) = 1
ORDER BY name
correctly returns all rows:
##################################
# Logins with sysadmin privilege #
##################################
NT SERVICE\SQLSERVERAGENT
NT SERVICE\SQLWriter
NT SERVICE\Winmgmt
sa
while the first query:
SELECT name
FROM master.dbo.sysdatabases
only returns the first row of the SELECT statement, of course the master database:
#####################
# List of Databases #
#####################
master
But as you can see I have plenty of databases in there.
Where am I wrong?

Note the array index at the end of the return statement:
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)[0]
That will return only the first row. Try:
return $(Execute-Query $ctpQuery "master" $instance $trusted $login $password)

Related

How do you script out SQL Server agent jobs to single or individual files

I've tried various Powershell scripts but they fail with:
The following exception occurred while trying to enumerate the collection: "An exception occurred while executing a Transact-SQL statement or batch.".
At H:\Create_SQLAgentJobSripts2.ps1:89 char:22
foreach ($job in $s.JobServer.Jobs)
~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
FullyQualifiedErrorId : ExceptionInGetEnumerator
What has gone wrong or how can I get better debugging on this error?
I executed this script:
.\Create_SQLAgentJobSripts2.ps1 .\ServerNameList.txt
Here's the script
param([String]$ServerListPath)
#write-host "Parameter: $ServerListPath"
#Load the input file into an Object array
$ServerNameList = get-content -path $ServerListPath
#Load the SQL Server SMO Assemly
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
#Create a new SqlConnection object
$objSQLConnection = New-Object System.Data.SqlClient.SqlConnection
#For each server in the array do the following.
foreach($ServerName in $ServerNameList)
{
Write-Host "Beginning with Server: $ServerName"
Try
{
$objSQLConnection.ConnectionString = "Server=$ServerName;Initial Catalog=CED_NCT_RESOURCE_TRACK;Persist Security Info=True;User ID=CEDNCTAdmin;Password=CEDNCTAdmin;"
Write-Host "Trying to connect to SQL Server instance on $ServerName..." -NoNewline
$objSQLConnection.Open() | Out-Null
Write-Host "Success."
$objSQLConnection.Close()
}
Catch
{
Write-Host -BackgroundColor Red -ForegroundColor White "Fail"
$errText = $Error[0].ToString()
if ($errText.Contains("network-related"))
{Write-Host "Connection Error. Check server name, port, firewall."}
Write-Host $errText
continue
}
# Won't be using this object again
Remove-Variable -Name objSQLConnection
#If the output folder does not exist then create it
$OutputFolder = ".\$ServerName"
if (!(Test-Path $OutputFolder))
{
write-host ("Creating directory: " + $OutputFolder)
New-Item -ItemType directory -Path $OutputFolder
}
else
{
write-host ("Directory already exists: " + $OutputFolder)
}
write-host "File: $(".\$OutputFolder\" + $($_.Name -replace '\\', '') + ".job.sql")"
# Connect to the instance using SMO
$s = new-object ('Microsoft.SqlServer.Management.Smo.Server') $ServerName
write-host ("SQL Server Edition: " + $s.Edition)
write-host ("SQL Agent ErrorLogFile: " + $s.JobServer.ErrorLogFile)
# Instantiate the Scripter object and set the base properties
$scrp = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($ServerName)
write-host ("SCRP ToString():" + $scrp.ToString())
write-host ("Test scrp - Server: " + $scrp.Server)
#The next step is to set the properties for the script files:
$scrp.Options.ScriptDrops = $False
$scrp.Options.WithDependencies = $False
$scrp.Options.IncludeHeaders = $True
$scrp.Options.AppendToFile = $False
$scrp.Options.ToFileOnly = $True
$scrp.Options.ClusteredIndexes = $True
$scrp.Options.DriAll = $True
$scrp.Options.Indexes = $False
$scrp.Options.Triggers = $False
$scrp.Options.IncludeIfNotExists = $True
#Now, we can cycle through the jobs and create scripts for each job on the server.
# Create the script file for each job
foreach ($job in $s.JobServer.Jobs)
{
$jobname = $job.Name
write-host ("Job: " + $jobname)
$jobfilename = ($OutputFolder + "\" + $jobname + ".job.sql")
$scrp.Options.FileName = $jobfilename
write-host "Filename: $jobfilename"
#This line blows up
$scrp.Script($job)
}
}
Possibly you're not instantiating the Server object correctly. Try the following instead...
# Alternative 1: With servername and port, using Trusted Connection...
$ServerName = 'YourServerName,1433'
$ServerConnection = New-Object Microsoft.SqlServer.Management.Common.ServerConnection -ArgumentList #( $ServerName )
# Alternative 2: With an SqlConnection object
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$ServerName;Initial Catalog=CED_NCT_RESOURCE_TRACK;Persist Security Info=True;User ID=CEDNCTAdmin;Password=CEDNCTAdmin;"
$SqlConnection.Open() | Out-Null
$ServerConnection = New-Object Microsoft.SqlServer.Management.Common.ServerConnection -ArgumentList #( $SqlConnection )
# Then...
$Server = New-Object Microsoft.SqlServer.Management.Smo.Server -ArgumentList #( $ServerConnection )
$Server.JobServer.Jobs | ForEach-Object {
Write-Host "Job: $($_.Name)"
}

Monitor a folder using Powershell and check it against a SQL table and send an email out if file doesn't exists in the last 6 hours

I am using powershell to check a folder and when a file gets added to the folder, it queries a sql table and if there hasn't been a file added in the last 6 hours then it will send an email to several people letting them know that the file was copied/uploaded to that folder.
I can send the email when a file gets added, but when I added the code to check the SQL table, it stopped working. Can someone help me figure out the rest of this script?
[code]
# make sure you adjust this to point to the folder you want to monitor
$PathToMonitor = "U:\temp\test"
explorer $PathToMonitor
$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path = $PathToMonitor
$FileSystemWatcher.IncludeSubdirectories = $true
# make sure the watcher emits events
$FileSystemWatcher.EnableRaisingEvents = $true
# define the code that should execute when a file change is detected
$Action = {
$details = $event.SourceEventArgs
$Name = $details.Name
$FullPath = $details.FullPath
$OldFullPath = $details.OldFullPath
$OldName = $details.OldName
$ChangeType = $details.ChangeType
$Timestamp = $event.TimeGenerated
$JustPath = Path.GetDirectoryName($FullPath)
# SQL Work ---------------------------------------------------------------------
$Server = 'SQL01'
$Database = 'FTP_Upload'
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "server='$Server';database='$Database';trusted_connection=true;"
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$text = "{0} was {1} at {2}" -f $FullPath, $ChangeType, $Timestamp
$sql = "IF Not Exists (Select 1 From Transmit Where DateDiff(IsNull(TimeGenerated, '01/01/2020 01:00:00 PM'), '$Timestamp') < 6 ) AND PathOnly = '$JustPath' )
BEGIN
Insert Transmit(FullPath, PathOnly, TimeGenerated)
Values('$FullPath', '$JustPath', '$Timestamp')
END "
Write-Host ""
Write-Host $text -ForegroundColor Green
Write-Host $sql
# you can also execute code based on change type here
switch ($ChangeType)
{
'Created' {
# Check SQL to see if there has been a file ftp'd in the last 6 hours ------
$Command.CommandText = $sql
$Command.ExecuteReader()
$Connection.Close()
# Send Email ---------------------------------
$EmailFrom = “email1#domain1.com”
$EmailTo = “email2#domain2.com, email3#domain3.com”
$Subject = “FTP Notification”
$Body = $text
$SMTPServer = “smtp.office365.com”
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“email1#domain1.com”, “password”);
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
Start-Sleep -Seconds 5
$SMTPClient.Dispose()
# this executes only when a file was renamed
$text = "File {0} was Created" -f $FullPath
Write-Host $text -ForegroundColor Yellow
}
default { Write-Host $_ -ForegroundColor Red -BackgroundColor White }
}
}
# add event handlers
$handlers = . {
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Changed -Action $Action -SourceIdentifier FSChange
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreate
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Deleted -Action $Action -SourceIdentifier FSDelete
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Renamed -Action $Action -SourceIdentifier FSRename
}
Write-Host "Watching for changes to $PathToMonitor"
try
{
do
{
Wait-Event -Timeout 1
Write-Host "." -NoNewline
} while ($true)
}
finally
{
# this gets executed when user presses CTRL+C
# remove the event handlers
Unregister-Event -SourceIdentifier FSChange
Unregister-Event -SourceIdentifier FSCreate
Unregister-Event -SourceIdentifier FSDelete
Unregister-Event -SourceIdentifier FSRename
# remove background jobs
$handlers | Remove-Job
# remove filesystemwatcher
$FileSystemWatcher.EnableRaisingEvents = $false
$FileSystemWatcher.Dispose()
"Event Handler disabled."
}
[/code]

Not able to access shared path in powershell

I want to take a SQL DB backup to a shared path and perform restoration through PS. Below is the code to perform the op
function restore-TemporaryInLocal($dbName,$backupPath,$sqlServer,$isOverWrite,$DecDBObj,$sqlInstanceName)
{
$percentEventHandler = [Microsoft.SqlServer.Management.Smo.PercentCompleteEventHandler] { Write-Host "Restoration progress : " $_.Percent "%" }
$completedEventHandler = [Microsoft.SqlServer.Management.Common.ServerMessageEventHandler] { Write-Host $_.Error.Message}
# Get the default file and log locations
# (If DefaultFile and DefaultLog are empty, use the MasterDBPath and MasterDBLogPath values)
$DataFileLoc = $sqlServer.Settings.DefaultFile
$LogFileLoc = $sqlServer.Settings.DefaultLog
if ($DataFileLoc.Length -eq 0) {
$DataFileLoc = $sqlServer.Information.MasterDBPath
}
if ($LogFileLoc.Length -eq 0) {
$LogFileLoc = $sqlServer.Information.MasterDBLogPath
}
# Identify the backup file to use, and the name of the database copy to create
#$BackupFile= 'D:\SQLJobs\Errdb2.bak'
#$RestoredDBName = 'ErrDB2_20101016'
# Build the physical file names for the database copy
$DBFile = $DataFileLoc + $dbname + '_Data.mdf'
$LogFile = $LogFileLoc + $dbname + '_Log.ldf'
# Use the backup file name to create the backup device
$bdi = new-object ('Microsoft.SqlServer.Management.Smo.BackupDeviceItem') ($backupPath, 'File')
# Create the new restore object, set the database name and add the backup device
$restoreObj = new-object('Microsoft.SqlServer.Management.Smo.Restore')
$restoreObj.Database = $dbName
$restoreObj.Devices.Add($bdi)
# Get the file list info from the backup file
$FileList = $restoreObj.ReadFileList($sqlServer)
foreach ($file in $FileList) {
$rsfile = new-object('Microsoft.SqlServer.Management.Smo.RelocateFile')
$rsfile.LogicalFileName = $file.LogicalName
if ($file.Type -eq 'D'){
$rsfile.PhysicalFileName = $DBFile
}
else {
$rsfile.PhysicalFileName = $LogFile
}
$restoreObj.RelocateFiles.Add($rsfile)
}
# Restore the database
$restoreObj.ReplaceDatabase=$isOverWrite;
#Write-Host "Replace DB :"$restoreObj.ReplaceDatabase
$restoreObj.add_PercentComplete($percentEventHandler)
$restoreObj.add_Complete($completedEventHandler)
if($isOverWrite -eq $true)
{
Write-Host "Taking DB Offline";
$script="ALTER DATABASE $dbname SET OFFLINE WITH ROLLBACK IMMEDIATE";
#Write-Host $script $dbname $sqlInstanceName
Invoke-SQLcmd -Server $sqlInstanceName -Database $dbName $script
Write-Host "Getting DB Online";
$DecDBObj.SetOnline();
}
Write-Host "Initiating DB restore..."
$restoreObj.SqlRestore($sqlServer)
}
function take-BackupToLocal($backupDirectory,$serverName,$backupDB,$isCopyOnly,$serverRef)
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
$percentEventHandler = [Microsoft.SqlServer.Management.Smo.PercentCompleteEventHandler] { Write-Host "Database backed up" $_.Percent "%" }
$completedEventHandler = [Microsoft.SqlServer.Management.Common.ServerMessageEventHandler] { Write-Host $_.Error.Message
Write-Host "Backup Path:"$targetPath
}
$dbList = $serverRef.Databases
$BackupDB =$BackupDB.Trim();
$DBexists=$false;
if(test-path $backupDirectory)
{
$timestamp = Get-Date -format yyyy-MM-dd-HHmmss
$targetPath = $backupDirectory + "\" + $backupDB + "_" + $timestamp + ".bak"
foreach ($database in $dbList | where { $_.IsSystemObject -eq $False })
{
$dbName = $database.Name
if($database.Name -eq $BackupDB -and $database.Status -ieq "normal"){
$DBexists=$true;
$smoBackup = New-Object ("Microsoft.SqlServer.Management.Smo.Backup")
$smoBackup.Action = "Database"
$smoBackup.BackupSetDescription = "Full Backup of " + $dbName
$smoBackup.BackupSetName = $dbName + " Backup"
$smoBackup.Database = $dbName
$smoBackup.MediaDescription = "Disk"
$smoBackup.CopyOnly=$isCopyOnly
$smoBackup.Devices.AddDevice($targetPath, "File")
$smoBackup.PercentCompleteNotification=5
$smoBackup.add_PercentComplete($percentEventHandler)
$smoBackup.add_Complete($completedEventHandler)
$smoBackup.SqlBackup($serverRef)
return $targetPath;
}else{
Write-Host "Cannot perform a backup as the DB is in:" $database.Status " mode";
}
}
if($DBexists -eq $false)
{
Write-Host "$BackupDB DB not found in $serverName.Please check the DB & Server details"
}
}
else
{
Write-Host "Cannot find the path specified. Contact admin"
Write-Host "backup path:"$backupDirectory
}
}
$sqlName= "*************"
$serverName="******";
# Set new or existing databse name to restote backup
$backupDB= "AdventureWorksDW2012"
# Set the existing backup file path
#$backupPath= "D:\Automation\Ps-scripts\Backups\tempdb1_2017-05-25-222232.bak"
#Load the required assemlies SMO and SmoExtended.
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
$percentEventHandler = [Microsoft.SqlServer.Management.Smo.PercentCompleteEventHandler] { Write-Host "Restoration progress : " $_.Percent "%" }
$completedEventHandler = [Microsoft.SqlServer.Management.Common.ServerMessageEventHandler] { Write-Host $_.Error.Message}
try{
# Connect SQL Server.
$sqlServer = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $sqlName
$ExistingDB=$sqlServer.Databases.Item($backupDB)
$backupDirectory="\\***********\ps_jobs_backup_shared";
$isCopyOnly=$true;
if($ExistingDB.EncryptionEnabled -eq $true)
{
$needToDecrypt = Read-Host -Prompt 'Specify if backup needs to be decrypted (Y/N)'
}
if($needToDecrypt -ieq "y")
{
#Write-Host "decryption code...."
$decServerSqlName="***************"
Write-Host "Initiating Backup..."
$DecryptDB="tempDB1"
$decSqlServer = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $decServerSqlName
$decServerSqlName="****************"
$isOverWrite=$true;
$DecDBObj=$decSqlServer.Databases.Item($DecryptDB)
$backupPath=take-BackupToLocal -backupDirectory $backupDirectory -serverName $sqlName -backupDB $backupDB -isCopyOnly $isCopyOnly -serverRef $sqlServer
restore-TemporaryInLocal -dbName $DecryptDB -backupPath $backupPath -sqlServer $decSqlServer -isOverWrite $isOverWrite -DecDBObj $DecDBObj -sqlInstanceName $decServerSqlName
}elseif($needToDecrypt -ieq "n")
{
Write-Host "Initiating a encrypted backup...";
take-BackupToLocal -backupDirectory $backupDirectory -serverName $sqlName -backupDB $backupDB -isCopyOnly $isCopyOnly -serverRef $sqlServer
}
}
catch
{
$_.Exception.GetBaseException().Message
}
Now the above code works fine. However when I execute the same code once again the TEST-PATH conditions fails[work-around: Need to re-open the PS IDE again after every run]
Below is the log for first 2 runs.
Specify if backup needs to be decrypted (Y/N): y
Initiating Backup...
Database backed up 5 %
Database backed up 10 %
Database backed up 100 %
BACKUP DATABASE successfully processed 25625 pages in 8.435 seconds (23.733 MB/sec).
Taking DB Offline
Getting DB Online
Initiating DB restore...
Restoration progress : 10 %
Restoration progress : 20 %
Restoration progress : 100 %
RESTORE DATABASE successfully processed 25625 pages in 7.429 seconds (26.946 MB/sec).
2nd Run:
Specify if backup needs to be decrypted (Y/N): y
Initiating Backup...
Cannot find the path specified. Contact admin
backup path: \\sanky555\ps_jobs_backup_shared

Exception when trying to create a new SQL account

I always get this error when i try to add a new login into my SQL server.
I searched it online and I found this on StackOverflow
Add Windows User to local SQL Server with PowerShell but this didn't solve it.
This is the error
Exception calling "Create" with "1" argument(s): "Create failed for Login 'bilal'. "
This is my code
$server="WIN-SH7H3HP7KMI\SQL2014"
$User="bilal"
$password="test"
if(!($svr.Logins.Contains($User)))
{
$login = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $server, $User
$login.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin
$login.PasswordExpirationEnabled = $false
$login.Create($password)
Write-Host("Login $loginName created successfully.")
}
#Matt this is the hole script
because it's giving me more error's who are lookalike the error i displayed in my question i was just focussing on that errror
$server="WIN-SH7H3HP7KMI\SQL2014"
$Database="master"
$User="bilal"
$Role="db_owner"
$Svr = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $server
# create new database and add to server
# [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO')
#$srv=new-Object Microsoft.SqlServer.Management.Smo.Server('(local)\Test')
#$db=New-Object Microsoft.SqlServer.Management.Smo.Database($srv,'Test_SMO_Database')
#$db.Create()
#Check Database Name entered correctly
$db = $svr.Databases[$Database]
if($db -eq $null)
{
Write-Host " $Database is not a valid database on $Server"
Write-Host " Databases on $Server are :"
$svr.Databases|select name
break
}
#Check Role exists on Database
$Rol = $db.Roles[$Role]
if($Rol -eq $null)
{
Write-Host " $Role is not a valid Role on $Database on $Server "
Write-Host " Roles on $Database are:"
$db.roles|select name
break
}
if(!($svr.Logins.Contains($User)))
{
$password="test"
$login = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $server, $User
$login.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin
$login.PasswordExpirationEnabled = $false
$login.Create($password)
Write-Host("Login $loginName created successfully.")
}
if (!($db.Users.Contains($User)))
{
# Add user to database
$usr = New-Object ('Microsoft.SqlServer.Management.Smo.User') ($db, $User)
$usr.Login = $User
$usr.Create()
#Add User to the Role
$Rol = $db.Roles[$Role]
$Rol.AddMember($User)
Write-Host "$User was not a login on $Database on $server"
Write-Host "$User added to $Database on $Server and $Role Role"
}
else
{
#Add User to the Role
$Rol = $db.Roles[$Role]
$Rol.AddMember($User)
Write-Host "$User added to $Role Role in $Database on $Server "
}

How to exit powershell invoked from psexec

I am trying to call a powershell script using psexec which connects to remote system
So from "Computer A" I call the batch file Aot.bat which is on "Computer B"
Aot.bat has a line which calls the powershell
powershell.exe %SystemRoot%\system32\aot.ps1 -ComputerName AotServ01 >>\Aot01\AOtShared\Yuma.txt;exit
I can see that the connection is made and powershell runs, but then it does not exit
So please advise what can be done or added
Aot.ps1 reads the Memory and CPU at the present Moment
[cmdletbinding()]
[cmdletbinding()]
param(
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = $env:computername)
begin {
Get-Module –ListAvailable | import-module
Add-PSSnapin Citrix*
Set-executionpolicy -scope currentuser -executionpolicy unrestricted
$date = Get-Date -Format yyyMMdd
$Zip = "\\na02\KCRC\IRD_KFLOWRPT\Citrix_" + $date + "\Citrix_" + $date + ".txt"
$time = Get-Date -format F
}
process
{
foreach($Computer in $Computername)
{
$free = ( Get-WMIObject Win32_OperatingSystem -ComputerName $computer ).FreePhysicalMemory
$phys = ( Get-WMIObject Win32_OperatingSystem -ComputerName $computer ).TotalVisibleMemorySize
$Percentage = (($phys-$free)/$Phys) * 100
$proc =get-counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 2
$cpu=($proc.readings -split ":")[-1]
write-host "`r`n*********************************************************************************"
write-host "`r`nComputer: " $computer
write-host "`r`n_________________________________________________________________________________"
write-host "`r`nPercentage Memory user Used: " $Percentage
write-host "`r`n"
write-host "`r`nPercentage CPU Used: " $cpu
write-host "`r`n_________________________________________________________________________________"
write-host "`r`n"
write-host $time
}
}
end
{
write-host "`r`n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
write-host "`r`n END OF FILE "
write-host "`r`n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
}
===============================================================================

Resources