Getting right to it, I'm using
WMIC /NODE: "computer_name" COMPUTERSYSTEM GET USERNAME
In a loop that feeds the computer name and records the returned username to compile a list of PCs and their current logged-in users:
Code: Select all
loop, parse, Connections_Table, `n, `r
{
LineNumTarget=
Username=
if A_Index=1
continue
RowNum++
StringSplit, Connections_Table_Field, A_LoopField, |
ComputerName = %Connections_Table_Field1%
;;; These are the commands used to get current username from PC
Full_Command := "WMIC `/NODE`: " . """" ComputerName """" . " COMPUTERSYSTEM GET USERNAME"
User_Output := ComObjCreate("WScript.Shell").Exec(Full_command).StdOut.ReadAll()
StringSplit, User_Output_Line, User_Output, `n, `r
If (!User_Output_Line0)
break
LineNumTarget := User_Output_Line0 - 2
Username%RowNum% := User_Output_Line%LineNumTarget%
}
I know after a few seconds that there will be no result, so in those cases, I'd like to kill the current iteration of the command. To (possibly) complicate matters, I have the script hide the console windows that pop up once per iteration of the loop.
Below is the full code if you need to see how I hide and whatnot, or if you just want a good laugh at my expense-- I just through a bunch of stuff together from previous experience or searches from the forum. Or if you are just bored and want to teach me how to properly do a lot of this stuff:
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#Include adosql.ahk
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetTitleMatchMode,2
DllCall("AllocConsole")
WinHide % "ahk_id " DllCall("GetConsoleWindow", "ptr")
Gui, Add, Text,+Center w350, Pick a server to view Connections:
IniRead, gui_position, %A_MyDocuments%\settings.ini, window position, gui_position, Center
Gui,Add,DropdownList,x90 w175 vServerSelection,RR FW1||FtW PRODFW|Test Server
Gui,Add,Button,gOk wp x10 y100,Ok
Gui,Add,Button,gCancel wp x200 y100,Cancel
Gui, Show,Autosize,Connections - Select Server
return
Ok:
Gui,Submit,, ;Remove Nohide if you want the GUI to hide.
If ServerSelection = RR FW1
ServerName = FW1.wookie.local
ELSE IF ServerSelection = FtW PRODFW
ServerName = PRODFW.fake.com
ELSE
ServerName = TEST1.wookie.local
WinGetPos, gui_x, gui_y,,, ahk_id %gui_id%
IniWrite, x%gui_x% y%gui_y%, %A_MyDocuments%\settings.ini, window position, gui_position
Gui,Destroy
connection_string =
( ltrim join;
DRIVER={SQL SERVER};SERVER=%ServerName%;UID=User;PWD=Password
)
Query_Connections =
(
SELECT
Connections.WID,
Connections.ConnDt
FROM
FDB.FW.Connections
ORDER BY ConnDt ASC
)
Connections_Table := ADOSQL(connection_string ";coldelim=|", Query_Connections)
FileDelete,Info.csv
RowNum=
loop, parse, Connections_Table, `n, `r
{
LineNumTarget=
Username=
if A_Index=1
continue
RowNum++
StringSplit, Connections_Table_Field, A_LoopField, |
ComputerName = %Connections_Table_Field1%
;;; These are the commands used to get current username from PC
Full_Command := "WMIC `/NODE`: " . """" ComputerName """" . " COMPUTERSYSTEM GET USERNAME"
User_Output := ComObjCreate("WScript.Shell").Exec(Full_command).StdOut.ReadAll()
StringSplit, User_Output_Line, User_Output, `n, `r
If (!User_Output_Line0)
break
LineNumTarget := User_Output_Line0 - 2
Username%RowNum% := User_Output_Line%LineNumTarget%
}
FileAppend, %Connections_Table%, Info.csv
Loop,Read,Info.csv
{
If (A_Index>1){
StringSplit, Type_,A_LoopReadLine,|
Index++
Data_%TypeIndex%++
Loop % Type_0
Data_%TypeIndex%_%Index%_%A_Index%:= Type_%A_Index%
LastType_1:=Type_1
Loop % Type_0
Type_%A_Index%=
} else
StringSplit,ColumnName,A_LoopReadLine,|
}
Gui,Add,ListView, r20 w500 gCopy,%ColumnName1%|Username|%ColumnName2%
Loop % Data_%A_ThisMenuItemPos%
{
LV_Add("",Data_%A_ThisMenuItemPos%_%A_Index%_1,Username%A_Index%,Data_%A_ThisMenuItemPos%_%A_Index%_2)
}
LV_ModifyCol(1,"AutoHdr"),LV_ModifyCol(2,"AutoHdr")
Gui,Show,,PCs Connected to %ServerName% - Double Click to Delete
Return
Cancel:
GuiClose:
Gui,Destroy
ExitApp
Copy:
If (A_GuiEvent!="DoubleClick")
Return
LV_GetText(WID_Selected,A_EventInfo,1)
LV_GetText(ConnDt_Selected,A_EventInfo,3)
Gui,Destroy
/*
SELECT *
FROM
FDB.FW.Connections
WHERE
WID='%WID_Selected%'
*/
Query_WID_Selected =
(
DECLARE @rc int
BEGIN TRY
BEGIN TRANSACTION
DELETE FROM FDB.FW.Connections
WHERE
WID='%WID_Selected%'
SET @rc = @@ROWCOUNT
IF @rc = 1
COMMIT TRAN
ELSE ROLLBACK TRAN
END TRY
BEGIN CATCH
IF @@TRANCOUNT `> 0
ROLLBACK TRAN
DECLARE @ErrorMessage NVARCHAR`(4000`) = ERROR_MESSAGE`(`)
DECLARE @ErrorSeverity INT = ERROR_SEVERITY`(`)
DECLARE @ErrorState INT = ERROR_STATE`(`)
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR `(@ErrorMessage, -- Message text.
`@ErrorSeverity, -- Severity.
`@ErrorState -- State.
`);
END CATCH
)
WID_To_Delete := ADOSQL(connection_string ";coldelim=|", Query_WID_Selected)
ExitApp
^Esc::Exitapp