Powershell script automation - sql-server

I managed to grab the concept of for-each and the SSMS application programming and also reading from excel file thru this question
Adding Servers to SQL Management Studio
This is the code that is working for me now
Import-Csv C:\sl.csv | ForEach-Object { New-Item $(Encode-Sqlname $_.Name) -ItemType Registration -Value ("server=;$($_.Name);integrated security=true") }
But I was having a problem with getting the user name and password to be auto-configured,
which means changing the above code to this
Import-Csv C:\sl.csv | ForEach-Object { New-Item $(Encode-Sqlname $_.Name) -ItemType Registration -Value ("server=;$($_.Name);integrated security=false") }
but that is ok that is how the people I am delivering the script to prefer, for security purposes.(even though I would like to know how to get it done :))
Now for further enhancement, there are quite a number of mirrored servers, like
server1/instance2a
server2/instance2b
so the thing is I want to know in the registered servers window
there are mirrored and the principal servers, which means when the server is registered the name I want to make it appear like this, server1/isntance2a (mirror), so when the user wants to login he easily knows which is the mirror or prinicipal server. So to determine this the sql query is this.
select mirroring_role_desc from sys.database_mirroring where database_id > 4 and mirroring_state is NOT NULL
the output of this will give me this
mirroring_role_desc
PRINCIPAL
PRINCIPAL
PRINCIPAL
PRINCIPAL
PRINCIPAL
This query will run and determine first if it is a mirrored instance, if it is then display the number of principal databases in the instance. From here I want to take the output and display the registered server name according to the specifications I mentioned above.
BUT when there is a failover the registered server name still shows as server1/instance2a even though it is the mirrored now, so as by now you can understand that I am trying to make this script dynamic so the user can run this when ever he wants or it is run every fortnight or something like that (not to worry about the schedule for now)

Related

Get-ItemProperty how to filter installed instances of SQL Server

I'm using this PowerShell command to get list of installed instances:
(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server').InstalledInstances
Output:
SQLEXPRESS
DBONE
The instance SQLEXPRESS is not running, so I would like to exclude it.
Can I filter the value data to get only the DBONE instance?
Well, the naive way is just to filter the output to exclude SQLEXPRESS:
(get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server').InstalledInstances |where-object {$_ -ne "SQLEXPRESS"}
If you need to correlate with the instances that are actually running, you'll need some way of distinguishing them in the Get-Process list ... like maybe the username they run under. Or you could use WMIC and inspect the startup directory?

How to delete a SQL Server local security group on Windows 10 Home using powershell?

I am trying to uninstall Microsoft SQL Server from my local machine. Uninstall instructions say one must delete all local security groups for SQL Server components before uninstalling, however I cannot figure how to do this on Windows 10 Home. I have found online two ways of doing this, but neither has worked.
The first way is through 'Control Panel > Administrative Tools > Computer Management > Local Users and Groups'. Because I have Home edition, the 'Local Users and Groups' option does not seem to be available so I cannot delete anything this way. Running MCM.exe and trying to add the respective snap-in doesn't work either (error says "This snap-in cannot be used with this edition of Windows...").
The second way is through PowerShell. If I use the cmdlet:
Get-LocalGroup
I can see a SQL Sever group called:
SQLServer2005SQLBrowserUser$<computername>.
However, if I try to delete it using the cmdlet:
Remove-LocalGroup -Name "SQLServer2005SQLBrowserUser$<computername>"
I get an error message saying that no such group exists, as it cannot read what follow the dollar sign ($). Since -Name doesn't accept wildcards here, I don't know how to tell PowerShell to delete this group.
What am I doing wrong here? Is there another way to do this?
Sorry if this is a newbie question, but I am currently at a loss and cannot find any other ideas how to do this.
Thank you.
Try:
Remove-LocalGroup -Name 'SQLServer2005SQLBrowserUser$<computername>'
The problem is that variable names are expanded inside a double-quoted string. Using single quotes prevents PowerShell from parsing the string and thinking $<computername> is a variable.

Invoke-sqlcmd to remote server issue: Could not find file

I'm trying to write a PowerShell script which will execute tsql query to only one remote server using invoke-sqlcmd. Those tsql queries are simple one like backup/restore database, create a user, etc.
Below is an extract of it :
# 5 # Create clientdb database on secondary server by restoring the full backup for primary
Try {
Invoke-sqlcmd -ServerInstance 'REMOTESQLSRV'`
-Username 'ts_sql' -Password 'somepassword'`
-InputFile "$LScltid\__01_On_Secondary_CreateDB2_srv2.sql"`
-ErrorAction Stop
Write-Host " clt_$id is now restored to secondary server "`
-ForegroundColor White -BackgroundColor Green
} Catch {
Write-Host " Restore operation for clt_$id did not succeed. Check the error logs " -ForegroundColor Black -BackgroundColor Red
}
My scripts always break here. For some reasons that i could not put my head on, invoke-sqlcmd does not use the variable "$LScltid" to resolve the path where it will find the .sql script.
Everytime i had to run it, it change the current directory to either the SQLERVER:\ provider or some other causing the script to failed at this step.
Am I doing this the right way? If so, how should i adapt the command to perform as I expect it to.?
UPDATE
Forgot to mention, if i run the script with the variables values hard-coded I'm able to get the result i need (in this case restoring a database from device).
Thanks for your feedbacks.
Odd thing, the command is now working. I don't really know what i've done wrong previously, but the exact same command is now working.
Just a heads up for those facing the same issue:
If you have to use Invoke-Sqlcmd in your scripts, beware of the provider change especially if the commands coming after Invoque-Sqlcmd are regulars one (get, set, copy, new, etc....)
In my case, somewhere in my script between two Invoke-sqlcmd commands i had to copy files from local to remote server. Everytime the command failed because the provider changed. As a workaround I set-location before copy-item command execution and that maneuver seemed to do the trick (don't know if its re-commanded tough.
Thanks Stackoverflow Team

Powershell User Issue Through SQL Server Agent

I am currently trying to run a Powershell script through SQL Server Agent, which completes its task without error if I run it through Powershell ISE on the desktop. The simple script is below (it's only being used for testing):
$test = "G:\test.txt"
if (Test-Path $testFile)
{
Remove-Item $test
}
When I run this through SQL Server Agent, it produces a successful output - no errors whatsoever, but does show that it's being run as a different user in the job history log, for instance domain\localmachine, whereas when I run the script through Powershell ISE, it shows domain\you.
As a note, I can't confirm this manually because what I tried to do was run the below script both locally and through SQL Server Agent in a job to see the output, but the job failed (and thus why I suspect it's a user issue). Therefore, I'm trusting SQL Server Agent as to the domain\locallmachine is running the job (the reason it won't delete the file).
([Environment]::UserDomainName + "\" + [Environment]::UserName) | out-file pssaved.txt
"$env:userdomain\$env:username" | out-file -append pssaved.txt
[Security.Principal.WindowsIdentity]::GetCurrent().Name | out-file -append pssaved.txt
## Locally this produces domain\you
## On SQL Server Agent, I receive the error: The error information returned by PowerShell is: 'SQL Server PowerShell provider error: Path SQLSERVER:\pssaved.txt does not exist. Please specify a valid path.'
Is there a way, through SQL Server Agent to run a job as my domain user, for instance domain\you instead of the domain\localmachine (at least, this would eliminate this possibility of an error)?
You can use a proxy for this. Check it out.

Ignoring users when deploying a database project from VS2008

I am currently working on an application that has different permissions/users for the local development environment and test. I want to be able to ignore the users and permissions when deploying to either environment. Under the .sqldeployment file, there seems to only be options for ignoring permissions (IgnorePermissions) and role membership (IgnoreRoleMembership) for a user, but not for ignoring the users themselves. Is this possible?
Sorry, not currently possible in the 2008 version of Visual Studio.
There isn't an obvious way - lots of requests for this feature here. The command-line tool, vsdbcmd.exe, suffers from the same problem.
As a workaround, I use a PowerShell script to remove users and schema authorization from the deployment SQL script. This could be run as a post-deploy step (not tried), or a TeamCity build step etc.
$rxUser = New-Object System.Text.RegularExpressions.Regex "PRINT[^;]*;\s*GO\s*CREATE USER \[[^\]]*](\s*WITH DEFAULT_SCHEMA = \[[^\]]*])?;\s*GO\s*", SingleLine
$rxSchema = New-Object System.Text.RegularExpressions.Regex "PRINT[^;]*;\s*GO\s*CREATE SCHEMA \[[^\]]*]\s*AUTHORIZATION \[[^\]]*];\s*GO\s*", SingleLine
Get-Item "*.sql" | ForEach-Object {
$input = [System.IO.File]::ReadAllText($_.FullName)
$input = $rxUser.Replace($input, "")
$input = $rxSchema.Replace($input, "")
$output = [System.IO.File]::CreateText($_.FullName)
$output.Write($input)
$output.Close()
}
The regex could be modified to ignore DROP USER statements too.

Resources