Reset IIS on multiple servers at once instead of looping through - vb.net

I am trying to reset IIS on a set of servers all at one time instead of looping through and resetting each one individually, but I can't seem to figure out how to do it. Could someone please give me an example? Thank you
I am using System.Diagnostics
With m_Process.StartInfo
.FileName = strFileName
.Arguments = String.Format("{0}{1}", server, strArguements)
.UseShellExecute = False
.CreateNoWindow = True
.RedirectStandardError = True
.RedirectStandardOutput = True
End With

I've seen a few questions today with similar conditions ("instead of looping") and I've been trying to figure out what the big deal is about looping. Since iisreset (what I am guessing is assigned to strFileName in your example) takes a single machine name, you are out of luck in that department.
I would assume that iisreset connects to the SCM on the target server and does a restart of the IIS Admin and dependent services.
I suppose you could roll your own iisreset.exe that took multiple servers on the command line, but internal to that you would have to use some kind of iteration.
Could you maybe explain why you can't or don't want to loop?

At some level you have to loop over the list of servers and send some message to each to instruct them to reset. Whether you do that by running iisreset with each server name or by some other means, you can't really make the loop go away.
However, if you're just saying that you want to start resetting all the servers as fast as possible rather than waiting for the first to finish resetting before you start resetting the second, it looks like you already have that. When you call m_Process.Start(), it should return as soon as the new iisreset process has started. As far as I can see, it doesn't block and wait until iisreset exits. Therefore, your iisreset processes should already run in parallel.

If I understand what you're asking, you're okay looping throught he servers, but you just don't want to wait for each server to complete before proceeding to the next one. Since ProcessStartInfo doesn't allow any way to detach from a process you're starting (be nice if it did), you can do it like this (obviously, missing your parameters and such):
Imports System.Threading
Class Restarter
Sub Main()
Dim ServerList As New List(Of String)
For Each server As String In ServerList
ThreadPool.QueueUserWorkItem(AddressOf RestartServer, server)
Next
End Sub
Sub RestartServer(ByVal Server As String)
Dim m_Process As System.Diagnostics.Process
With m_Process.StartInfo
.FileName = strFileName
.Arguments = String.Format("{0}{1}", Server, strArguements)
.UseShellExecute = False
.CreateNoWindow = True
.RedirectStandardError = True
.RedirectStandardOutput = True
End With
m_Process.Start()
End Sub
End Class

Related

Disconnecting users and removing .laccdb file - Office 365

I have .adcde frontend + .accdb backend database located on local shared drive, used by 10 users at the moment. They are using shortcuts to access frontend file. I have struggled to make regular updates as users constantly left DB open so I implemented idea from MSDN website ( https://learn.microsoft.com/en-us/office/troubleshoot/access/shut-down-custom-application-remotely )
Solution works well on my machine, however, when utilized in user environment, it seems to leave .laccdb locks on both frontend and backend (which I deduct should be closed in moment when last connection to frontend closes)
Any hints? Do I understand this structure incorrectly?
Private Sub Form_Open(Cancel As Integer)
boolCountDown = False
DoCmd.Maximize
DoCmd.Restore
Me.Visible = False
End Sub
Private Sub Form_Timer()
On Error GoTo Err_Form_Timer
Dim strFileName As String
strFileName = Dir(filelocation/chkfile.ozx)
If boolCountDown = False Then
If strFileName <> "chkfile.ozx" Then
boolCountDown = True
intCountDownMinutes = 2
End If
Else
intCountDownMinutes = intCountDownMinutes - 1
'DoCmd.OpenForm "aShutDownWarning"
Me.Visible = True
Me.SetFocus
Forms!aShutDownWarning!txtWarning.Caption = "This application will be shut down in approximately " & intCountDownMinutes & " minute(s) due to maintenance works. Please save all work."
If intCountDownMinutes < 1 Then
Application.Quit acQuitSaveAll
End If
End If
end sub
That should work but I guess, since the laccdb files are still there, that one or more user are actually not logged out.
If they logg out from their account or from their computer the Access files can still be open but not running, so your code is not really running.
I solved a similar situation by adding usernames to a table when they start the program and delete the same username when program are closed. That way I could see users that was not logged out by a similar code.
If you're able to delete the .laccdb files manually then no one is still logged in and some user's Access session was simply unable to clean up after itself when it terminated. This might be caused by a user not having delete access to the folder where the .laccdb file is. Otherwise, someone is still logged in. You can use the Jet UserRoster to see who is logged in. If you want to make your own viewer see https://learn.microsoft.com/en-us/office/troubleshoot/access/determine-who-is-logged-on-to-database or see this utility at https://www.utteraccess.com/topics/1897146

Using Self Code Signing Certificates for Publish purpose

I searched many times in this topic but with no luck, I have an application on WPF that use Click Once to published and there fore I can't use Admin Privilege, and I need to implement some actions in the installation Process like restart SQL server for example and for that I need Admin Privilege and since i start publishing using click once I had to remove Admin Privilege now, i tried restart my application to force Admin rights using the following code but didn't work
Public Function IsRunAsAdmin() As Boolean
Try
Dim id As WindowsIdentity = WindowsIdentity.GetCurrent()
Dim principal As WindowsPrincipal = New WindowsPrincipal(id)
Return principal.IsInRole(WindowsBuiltInRole.Administrator)
Catch __unusedException1__ As Exception
Return False
End Try
End Function
Public Sub AdminRelauncher()
If Not IsRunAsAdmin() Then
Dim proc As ProcessStartInfo = New ProcessStartInfo()
Dim procExecuting As New Process
proc.UseShellExecute = True
proc.WorkingDirectory = Environment.CurrentDirectory
proc.FileName = Assembly.GetEntryAssembly().CodeBase
proc.Verb = "runas"
Try
procExecuting = Process.Start(proc)
Application.ExitThread()
Application.Exit()
Catch ex As Exception
Console.WriteLine("This program must be run as an administrator! " & vbLf & vbLf & ex.ToString())
End Try
End If
End Sub
I still get the Error "Can not open MSSQL$****** on computer" after i searched of course i found the cause is admin rights needed.
So now i'm working on Code Signing Certificates as some one advise me that this will work for me.
but i'm an individual and my application price is not high enough to buy a paid certificate so i was wondering if i can make a self Code Signing Certificate and use it with click once.
Thank you.
I finally manged to figure out the problem my self, it was the admin rights.
The problem was that the code simply need like 2-3 mile seconds to execute so when i tracked the code i found that my code manged to stop the service indeed but wasn't able to start it again as it didn't take the time for the service to fully stop.
The solution was simple as it just needed couple of seconds to after it execute the code to stop the service.
So simply need to add a code in between.
First
Imports System.Threading
Then use the code as following
Dim service As ServiceController = New ServiceController("SQL Server (SQLEXPRESS)")
service.Stop()
Thread.Sleep(10000)
service.Start()
You see the code where Thread.sleep is make the application wait 10 seconds before it complete to execute the code.
This time is depends on the machine it self, 2-3 sec was enough but some other machine needed more time so to be in the safe side just add more seconds as I did.
Thank you, and "Stay Safe".

Starting app with Process.Start does not show in Task Manager until main application exits

I start a small application from my main application using process.start. Here is an abstract of my code: (I removed all the error-checking just for clarity...)
Dim proc as New Process
Dim si As New ProcessStartInfo
si.FileName = "SourceMonitor.exe"
si.Arguments = "guid=" & GUID & " name=" & Name & " timeout=0"
si.UseShellExecute = True
si.CreateNoWindow = True
Proc.StartInfo = si
Proc.EnableRaisingEvents = True
AddHandler Proc.Exited, AddressOf procExitEventHandler
Proc.Start()
What happens is that the new app SourceMonitor will not show up in Task Manager - but I want it to. However, it Does show up as soon as the program that launched it (using process.start) exits. This seems odd to me!
I've tried setting UseShellExecute to False, and even tried a different approach using si (my ProcessStartInfo) to
WindowStyle = ProcessWindowStyle.Hidden
si.UseShellExecute = False 'this is required when using processWindowStyle.hidden
In every case the app does not show up in Task Manager until the main program exits.
Does anyone know of a way to make sure my app does show up in Task Manager? It helps when I need to diagnose a customer issue - because I need to see if the SourceMonitor is running.
Ok - found the "issue" - and it was rather obvious...
The second process is owned by the first. It doesn't show up in the list as an independent process, rather it shows up as a child of the main process. The Task Manager has a drop-down arrow on the main application.
v MainApplication
- SourceMonitor
Clicking the dropdown shows the SourceMonitor it shelled. If I stop the main application the SourceMonitor does become an independent app and then shows up on the regular list. This actually works better than I had hoped.

VB.Net - Elevate Privileges

How can I elevate my program on demand? (For example when clicking a button).
I don't like to set the privileges in the manifests file, I am talking about
elevating my VB.Net program at runtime.
Does anyone know how to do this?
I appreciate every helpful answer :)
You can't elevate your program on demand as such. Your options are:
Restart your application using the RunAs verb (see start batch file from within vb.net as admin)
Start your application with the required privileges in the first place
Okay, using the RunAs-Method to elevate it. (This requires a restart tho)
Private Sub RestartElevated()
Dim startInfo As New ProcessStartInfo()
startInfo.UseShellExecute = True
startInfo.WorkingDirectory = Environment.CurrentDirectory
startInfo.FileName = Application.ExecutablePath
startInfo.Verb = "runas"
Try
Dim p As Process = Process.Start(startInfo)
Catch ex As System.ComponentModel.Win32Exception
Return
End Try
Application.[Exit]()
End Sub

An issue with reading DB when program runs at startup in vb.net

I'm new here and to vb.net and I'm stuck on something that I feel SHOULD be simple to resolve. I setup my program to let the user decide if he or she wants to have the program run at windows start. It actually works fine as it is assigning the registry value to CurrentUser instead of Local Machine because of admin rights needing to be bypassed. However, when I restart my computer the program comes up like normal, but it will not read my access db that is located in the same folder as the program; it tries to read the DB from Windows\System32.
Is there a way to force it to read from the executablepath instead of System32?
Here is my simple code:
Private Sub startup()
If cbStartup.Checked = True Then
My.Computer.Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", True).SetValue("CC_List", System.Windows.Forms.Application.ExecutablePath)
ElseIf cbStartup.Checked = False Then
My.Computer.Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", True).DeleteValue("CC_List", False)
End If
End Sub
So when the O/S starts your program the Current Directory is %windir%\System32.
You need to either adjust all your existing paths to be explicitly relative to Application.ExecutablePath, or put
My.Computer.FileSystem.CurrentDirectory = My.Application.Info.DirectoryPath
at the start of your program (which is the modern version of ChDir ...).