R ಮತ್ತು PowerShell ಅನ್ನು ಬಳಸಿಕೊಂಡು ವರ್ಚುವಲ್ ಯಂತ್ರಗಳ ಆರೋಗ್ಯದ ಕುರಿತು ದೈನಂದಿನ ವರದಿಗಳು

R ಮತ್ತು PowerShell ಅನ್ನು ಬಳಸಿಕೊಂಡು ವರ್ಚುವಲ್ ಯಂತ್ರಗಳ ಆರೋಗ್ಯದ ಕುರಿತು ದೈನಂದಿನ ವರದಿಗಳು

ಪ್ರವೇಶ

ಶುಭ ಅಪರಾಹ್ನ. ಅರ್ಧ ವರ್ಷದಿಂದ ನಾವು ವರ್ಚುವಲ್ ಯಂತ್ರಗಳ ಸ್ಥಿತಿಯ ಕುರಿತು ವರದಿಗಳನ್ನು ಉತ್ಪಾದಿಸುವ ಸ್ಕ್ರಿಪ್ಟ್ (ಅಥವಾ ಬದಲಿಗೆ ಸ್ಕ್ರಿಪ್ಟ್‌ಗಳ ಸೆಟ್) ಅನ್ನು ಚಾಲನೆ ಮಾಡುತ್ತಿದ್ದೇವೆ (ಮತ್ತು ಮಾತ್ರವಲ್ಲ). ನನ್ನ ಸೃಷ್ಟಿ ಅನುಭವ ಮತ್ತು ಕೋಡ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ನಾನು ನಿರ್ಧರಿಸಿದೆ. ಟೀಕೆಗಾಗಿ ಮತ್ತು ಈ ವಸ್ತುವು ಯಾರಿಗಾದರೂ ಉಪಯುಕ್ತವಾಗಬಹುದು ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ.

ಅಗತ್ಯದ ರಚನೆ

ನಾವು ಬಹಳಷ್ಟು ವರ್ಚುವಲ್ ಯಂತ್ರಗಳನ್ನು ಹೊಂದಿದ್ದೇವೆ (ಸುಮಾರು 1500 VM ಗಳನ್ನು 3 vCenters ನಲ್ಲಿ ವಿತರಿಸಲಾಗಿದೆ). ಹೊಸದನ್ನು ರಚಿಸಲಾಗಿದೆ ಮತ್ತು ಹಳೆಯದನ್ನು ಆಗಾಗ್ಗೆ ಅಳಿಸಲಾಗುತ್ತದೆ. ಕ್ರಮವನ್ನು ಕಾಯ್ದುಕೊಳ್ಳಲು, VM ಗಳನ್ನು ಉಪವ್ಯವಸ್ಥೆಗಳಾಗಿ ವಿಭಜಿಸಲು vCenter ಗೆ ಹಲವಾರು ಕಸ್ಟಮ್ ಕ್ಷೇತ್ರಗಳನ್ನು ಸೇರಿಸಲಾಯಿತು, ಅವುಗಳು ಪರೀಕ್ಷಾರ್ಥವಾಗಿವೆಯೇ ಮತ್ತು ಯಾರಿಂದ ಮತ್ತು ಯಾವಾಗ ರಚಿಸಲ್ಪಟ್ಟವು ಎಂಬುದನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಮಾನವ ಅಂಶವು ಅರ್ಧಕ್ಕಿಂತ ಹೆಚ್ಚು ಯಂತ್ರಗಳು ಖಾಲಿ ಜಾಗಗಳೊಂದಿಗೆ ಉಳಿದಿವೆ ಎಂಬ ಅಂಶಕ್ಕೆ ಕಾರಣವಾಯಿತು, ಇದು ಕೆಲಸವನ್ನು ಸಂಕೀರ್ಣಗೊಳಿಸಿತು. ಪ್ರತಿ ಆರು ತಿಂಗಳಿಗೊಮ್ಮೆ, ಯಾರಾದರೂ ಹುಚ್ಚರಾಗುತ್ತಾರೆ ಮತ್ತು ಈ ಡೇಟಾವನ್ನು ನವೀಕರಿಸಲು ಕೆಲಸ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಿದರು, ಆದರೆ ಫಲಿತಾಂಶವು ಒಂದೂವರೆ ವಾರದ ನಂತರ ಪ್ರಸ್ತುತವಾಗುವುದನ್ನು ನಿಲ್ಲಿಸಿತು.
ಯಂತ್ರಗಳ ರಚನೆ, ಅವುಗಳ ರಚನೆಯ ಪ್ರಕ್ರಿಯೆ ಇತ್ಯಾದಿಗಳಿಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಇರಬೇಕು ಎಂದು ಪ್ರತಿಯೊಬ್ಬರೂ ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತಾರೆ ಎಂದು ನಾನು ಈಗಿನಿಂದಲೇ ಸ್ಪಷ್ಟಪಡಿಸುತ್ತೇನೆ. ಮತ್ತು ಇತ್ಯಾದಿ. ಮತ್ತು ಅದೇ ಸಮಯದಲ್ಲಿ, ಪ್ರತಿಯೊಬ್ಬರೂ ಈ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಕಟ್ಟುನಿಟ್ಟಾಗಿ ಅನುಸರಿಸುತ್ತಾರೆ ಮತ್ತು ಎಲ್ಲವೂ ಕ್ರಮದಲ್ಲಿದೆ. ದುರದೃಷ್ಟವಶಾತ್, ಇದು ಇಲ್ಲಿ ಅಲ್ಲ, ಆದರೆ ಇದು ಲೇಖನದ ವಿಷಯವಲ್ಲ :)

ಸಾಮಾನ್ಯವಾಗಿ, ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ಭರ್ತಿ ಮಾಡುವ ಸರಿಯಾದತೆಯನ್ನು ಪರಿಶೀಲಿಸುವುದನ್ನು ಸ್ವಯಂಚಾಲಿತಗೊಳಿಸಲು ನಿರ್ಧಾರವನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ.
ಎಲ್ಲಾ ಜವಾಬ್ದಾರಿಯುತ ಎಂಜಿನಿಯರ್‌ಗಳು ಮತ್ತು ಅವರ ಮೇಲಧಿಕಾರಿಗಳಿಗೆ ತಪ್ಪಾಗಿ ಭರ್ತಿ ಮಾಡಿದ ಯಂತ್ರಗಳ ಪಟ್ಟಿಯೊಂದಿಗೆ ದೈನಂದಿನ ಪತ್ರವು ಉತ್ತಮ ಆರಂಭವಾಗಿದೆ ಎಂದು ನಾವು ನಿರ್ಧರಿಸಿದ್ದೇವೆ.

ಈ ಹಂತದಲ್ಲಿ, ನನ್ನ ಸಹೋದ್ಯೋಗಿಯೊಬ್ಬರು ಈಗಾಗಲೇ ಪವರ್‌ಶೆಲ್‌ನಲ್ಲಿ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿದ್ದಾರೆ, ಇದು ಪ್ರತಿದಿನ, ಒಂದು ವೇಳಾಪಟ್ಟಿಯ ಪ್ರಕಾರ, ಎಲ್ಲಾ vCenters ಗಳ ಎಲ್ಲಾ ಯಂತ್ರಗಳ ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ ಮತ್ತು 3 csv ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು (ಪ್ರತಿಯೊಂದೂ ತನ್ನದೇ ಆದ vCenter ಗೆ) ಉತ್ಪಾದಿಸುತ್ತದೆ, ಅದನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿದೆ. ಒಂದು ಸಾಮಾನ್ಯ ಡಿಸ್ಕ್. ಈ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಆಧಾರವಾಗಿ ತೆಗೆದುಕೊಳ್ಳಲು ಮತ್ತು R ಭಾಷೆಯನ್ನು ಬಳಸುವ ಚೆಕ್‌ಗಳೊಂದಿಗೆ ಪೂರಕಗೊಳಿಸಲು ನಿರ್ಧರಿಸಲಾಯಿತು, ಅದರೊಂದಿಗೆ ನಮಗೆ ಸ್ವಲ್ಪ ಅನುಭವವಿದೆ.

ಅಂತಿಮಗೊಳಿಸುವಿಕೆಯ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ, ಪರಿಹಾರವು ಮೇಲ್ ಮೂಲಕ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಂಡಿತು, ಮುಖ್ಯ ಮತ್ತು ಐತಿಹಾಸಿಕ ಕೋಷ್ಟಕವನ್ನು ಹೊಂದಿರುವ ಡೇಟಾಬೇಸ್ (ಇದನ್ನು ನಂತರ ಹೆಚ್ಚು), ಹಾಗೆಯೇ vM ನ ನಿಜವಾದ ರಚನೆಕಾರರನ್ನು ಮತ್ತು ಅವುಗಳ ರಚನೆಯ ಸಮಯವನ್ನು ಕಂಡುಹಿಡಿಯಲು vSphere ಲಾಗ್‌ಗಳ ವಿಶ್ಲೇಷಣೆ.

IDE RStudio ಡೆಸ್ಕ್‌ಟಾಪ್ ಮತ್ತು PowerShell ISE ಅನ್ನು ಅಭಿವೃದ್ಧಿಗಾಗಿ ಬಳಸಲಾಗಿದೆ.

ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಸಾಮಾನ್ಯ ವಿಂಡೋಸ್ ವರ್ಚುವಲ್ ಯಂತ್ರದಿಂದ ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ.

ಸಾಮಾನ್ಯ ತರ್ಕದ ವಿವರಣೆ.

ಸ್ಕ್ರಿಪ್ಟ್‌ಗಳ ಸಾಮಾನ್ಯ ತರ್ಕವು ಈ ಕೆಳಗಿನಂತಿರುತ್ತದೆ.

  • ನಾವು ಪವರ್‌ಶೆಲ್ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ವರ್ಚುವಲ್ ಗಣಕಗಳಲ್ಲಿ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುತ್ತೇವೆ, ಅದನ್ನು ನಾವು R ಮೂಲಕ ಕರೆಯುತ್ತೇವೆ ಮತ್ತು ಫಲಿತಾಂಶವನ್ನು ಒಂದು csv ಆಗಿ ಸಂಯೋಜಿಸುತ್ತೇವೆ. ಭಾಷೆಗಳ ನಡುವಿನ ಹಿಮ್ಮುಖ ಸಂವಹನವನ್ನು ಇದೇ ರೀತಿ ಮಾಡಲಾಗುತ್ತದೆ. (ವೇರಿಯೇಬಲ್‌ಗಳ ರೂಪದಲ್ಲಿ R ನಿಂದ PowerShell ಗೆ ಡೇಟಾವನ್ನು ನೇರವಾಗಿ ಚಾಲನೆ ಮಾಡಲು ಸಾಧ್ಯವಿತ್ತು, ಆದರೆ ಇದು ಕಷ್ಟಕರವಾಗಿದೆ ಮತ್ತು ಮಧ್ಯಂತರ csvs ಡೀಬಗ್ ಮಾಡಲು ಮತ್ತು ಯಾರೊಂದಿಗಾದರೂ ಮಧ್ಯಂತರ ಫಲಿತಾಂಶಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಸುಲಭವಾಗುತ್ತದೆ).
  • R ಅನ್ನು ಬಳಸಿಕೊಂಡು, ನಾವು ಪರಿಶೀಲಿಸುತ್ತಿರುವ ಕ್ಷೇತ್ರಗಳಿಗೆ ಮಾನ್ಯವಾದ ನಿಯತಾಂಕಗಳನ್ನು ರೂಪಿಸುತ್ತೇವೆ. - ನಾವು ವರ್ಡ್ ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ರಚಿಸುತ್ತಿದ್ದೇವೆ ಅದು ಮಾಹಿತಿ ಪತ್ರದಲ್ಲಿ ಸೇರಿಸಲು ಈ ಕ್ಷೇತ್ರಗಳ ಮೌಲ್ಯಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ, ಅದು ಸಹೋದ್ಯೋಗಿಗಳ ಪ್ರಶ್ನೆಗಳಿಗೆ ಉತ್ತರವಾಗಿರುತ್ತದೆ "ಇಲ್ಲ, ಆದರೆ ನಾನು ಇದನ್ನು ಹೇಗೆ ಭರ್ತಿ ಮಾಡಬೇಕು?"
  • R ಬಳಸಿಕೊಂಡು csv ಯಿಂದ ಎಲ್ಲಾ VM ಗಳಿಗೆ ನಾವು ಡೇಟಾವನ್ನು ಲೋಡ್ ಮಾಡುತ್ತೇವೆ, ಡೇಟಾಫ್ರೇಮ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ, ಅನಗತ್ಯ ಕ್ಷೇತ್ರಗಳನ್ನು ತೆಗೆದುಹಾಕುತ್ತೇವೆ ಮತ್ತು ಎಲ್ಲಾ VM ಗಳಿಗೆ ಸಾರಾಂಶ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರುವ ಮಾಹಿತಿ xlsx ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ, ಅದನ್ನು ನಾವು ಹಂಚಿಕೊಂಡ ಸಂಪನ್ಮೂಲಕ್ಕೆ ಅಪ್‌ಲೋಡ್ ಮಾಡುತ್ತೇವೆ.
  • ಎಲ್ಲಾ VM ಗಳಿಗಾಗಿ ಡೇಟಾಫ್ರೇಮ್‌ಗೆ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ಭರ್ತಿ ಮಾಡುವ ಸರಿಯಾಗಿರುವಿಕೆಗಾಗಿ ನಾವು ಎಲ್ಲಾ ಪರಿಶೀಲನೆಗಳನ್ನು ಅನ್ವಯಿಸುತ್ತೇವೆ ಮತ್ತು ತಪ್ಪಾಗಿ ತುಂಬಿದ ಕ್ಷೇತ್ರಗಳೊಂದಿಗೆ (ಮತ್ತು ಈ ಕ್ಷೇತ್ರಗಳು ಮಾತ್ರ) VM ಗಳನ್ನು ಹೊಂದಿರುವ ಟೇಬಲ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ.
  • ನಾವು VM ಗಳ ಫಲಿತಾಂಶದ ಪಟ್ಟಿಯನ್ನು ಮತ್ತೊಂದು PowerShell ಸ್ಕ್ರಿಪ್ಟ್‌ಗೆ ಕಳುಹಿಸುತ್ತೇವೆ, ಇದು VM ರಚನೆಯ ಈವೆಂಟ್‌ಗಳಿಗಾಗಿ vCenter ಲಾಗ್‌ಗಳನ್ನು ನೋಡುತ್ತದೆ, ಇದು VM ಮತ್ತು ಉದ್ದೇಶಿತ ರಚನೆಕಾರರ ರಚನೆಯ ಅಂದಾಜು ಸಮಯವನ್ನು ಸೂಚಿಸಲು ನಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಯಾರ ಕಾರು ಎಂದು ಯಾರೂ ಒಪ್ಪಿಕೊಳ್ಳದ ಸಂದರ್ಭದಲ್ಲಿ ಇದು. ಈ ಸ್ಕ್ರಿಪ್ಟ್ ತ್ವರಿತವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ, ವಿಶೇಷವಾಗಿ ಬಹಳಷ್ಟು ಲಾಗ್‌ಗಳಿದ್ದರೆ, ನಾವು ಕಳೆದ 2 ವಾರಗಳಲ್ಲಿ ಮಾತ್ರ ನೋಡುತ್ತೇವೆ ಮತ್ತು ಒಂದೇ ಸಮಯದಲ್ಲಿ ಹಲವಾರು VM ಗಳಲ್ಲಿ ಮಾಹಿತಿಯನ್ನು ಹುಡುಕಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ವರ್ಕ್‌ಫ್ಲೋ ಅನ್ನು ಸಹ ಬಳಸುತ್ತೇವೆ. ಉದಾಹರಣೆ ಸ್ಕ್ರಿಪ್ಟ್ ಈ ಕಾರ್ಯವಿಧಾನದ ಬಗ್ಗೆ ವಿವರವಾದ ಕಾಮೆಂಟ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿದೆ. ನಾವು ಫಲಿತಾಂಶವನ್ನು csv ಗೆ ಸೇರಿಸುತ್ತೇವೆ, ಅದನ್ನು ನಾವು ಮತ್ತೆ R ಗೆ ಲೋಡ್ ಮಾಡುತ್ತೇವೆ.
  • ನಾವು ಸುಂದರವಾಗಿ ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡಲಾದ xlsx ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ, ಅದರಲ್ಲಿ ತಪ್ಪಾಗಿ ತುಂಬಿದ ಕ್ಷೇತ್ರಗಳನ್ನು ಕೆಂಪು ಬಣ್ಣದಲ್ಲಿ ಹೈಲೈಟ್ ಮಾಡಲಾಗುತ್ತದೆ, ಕೆಲವು ಕಾಲಮ್‌ಗಳಿಗೆ ಫಿಲ್ಟರ್‌ಗಳನ್ನು ಅನ್ವಯಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಉದ್ದೇಶಿತ ರಚನೆಕಾರರನ್ನು ಹೊಂದಿರುವ ಹೆಚ್ಚುವರಿ ಕಾಲಮ್‌ಗಳು ಮತ್ತು VM ಅನ್ನು ರಚಿಸುವ ಸಮಯವನ್ನು ಸೂಚಿಸಲಾಗುತ್ತದೆ.
  • ನಾವು ಇಮೇಲ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ, ಅಲ್ಲಿ ನಾವು ಮಾನ್ಯವಾದ ಕ್ಷೇತ್ರ ಮೌಲ್ಯಗಳನ್ನು ವಿವರಿಸುವ ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ಲಗತ್ತಿಸುತ್ತೇವೆ, ಹಾಗೆಯೇ ಕ್ಷೇತ್ರಗಳಲ್ಲಿ ತಪ್ಪಾಗಿ ತುಂಬಿದ ಟೇಬಲ್ ಅನ್ನು ಲಗತ್ತಿಸುತ್ತೇವೆ. ಪಠ್ಯದಲ್ಲಿ ನಾವು ತಪ್ಪಾಗಿ ರಚಿಸಲಾದ VM ಗಳ ಒಟ್ಟು ಸಂಖ್ಯೆ, ಹಂಚಿದ ಸಂಪನ್ಮೂಲಕ್ಕೆ ಲಿಂಕ್ ಮತ್ತು ಪ್ರೇರಕ ಚಿತ್ರವನ್ನು ಸೂಚಿಸುತ್ತೇವೆ. ತಪ್ಪಾಗಿ ತುಂಬಿದ VM ಗಳಿಲ್ಲದಿದ್ದರೆ, ನಾವು ಸಂತೋಷದ ಪ್ರೇರಕ ಚಿತ್ರದೊಂದಿಗೆ ಮತ್ತೊಂದು ಪತ್ರವನ್ನು ಕಳುಹಿಸುತ್ತೇವೆ.
  • ನಾವು SQL ಸರ್ವರ್ ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಎಲ್ಲಾ VM ಗಳಿಗೆ ಡೇಟಾವನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತೇವೆ, ಐತಿಹಾಸಿಕ ಕೋಷ್ಟಕಗಳ ಕಾರ್ಯಗತಗೊಳಿಸಿದ ಕಾರ್ಯವಿಧಾನವನ್ನು ಗಣನೆಗೆ ತೆಗೆದುಕೊಂಡು (ಬಹಳ ಆಸಕ್ತಿದಾಯಕ ಕಾರ್ಯವಿಧಾನ - ಅದರ ಬಗ್ಗೆ ಹೆಚ್ಚು ನಂತರ)

ವಾಸ್ತವವಾಗಿ ಸ್ಕ್ರಿಪ್ಟ್‌ಗಳು

ಮುಖ್ಯ R ಕೋಡ್ ಫೈಲ್

# Путь к рабочей директории (нужно для корректной работы через виндовый планировщик заданий)
setwd("C:ScriptsgetVm")
#### Подгружаем необходимые пакеты ####
library(tidyverse)
library(xlsx)
library(mailR)
library(rmarkdown)
##### Определяем пути к исходным файлам и другие переменные #####
source(file = "const.R", local = T, encoding = "utf-8")
# Проверяем существование файла со всеми ВМ и удаляем, если есть.
if (file.exists(filenameVmCreationRules)) {file.remove(filenameVmCreationRules)}
#### Создаём вордовский документ с допустимыми полями
render("VM_name_rules.Rmd",
output_format = word_document(),
output_file = filenameVmCreationRules)
# Проверяем существование файла со всеми ВМ и удаляем, если есть
if (file.exists(allVmXlsxPath)) {file.remove(allVmXlsxPath)}
#### Забираем данные по всем машинам через PowerShell скрипт. На выходе получим csv.
system(paste0("powershell -File ", getVmPsPath))
# Полный df
fullXslx_df <- allVmXlsxPath %>% 
read.csv2(stringsAsFactors = FALSE)
# Проверяем корректность заполненных полей
full_df <- fullXslx_df %>%
mutate(
# Сначала убираем все лишние пробелы и табуляции, потом учитываем разделитель запятую, потом проверяем вхождение в допустимые значения,
isSubsystemCorrect = Subsystem %>% 
gsub("[[:space:]]", "", .) %>% 
str_split(., ",") %>% 
map(function(x) (all(x %in% AllowedValues$Subsystem))) %>%
as.logical(),
isOwnerCorrect = Owner %in% AllowedValues$Owner,
isCategoryCorrect = Category %in% AllowedValues$Category,
isCreatorCorrect = (!is.na(Creator) & Creator != ''),
isCreation.DateCorrect = map(Creation.Date, IsDate)
)
# Проверяем существование файла со всеми ВМ и удаляем, если есть.
if (file.exists(filenameAll)) {file.remove(filenameAll)}
#### Формируем xslx файл с отчётом ####
# Общие данные на отдельный лист
full_df %>% write.xlsx(file=filenameAll,
sheetName=names[1],
col.names=TRUE,
row.names=FALSE,
append=FALSE)
#### Формируем xslx файл с неправильно заполненными полями ####
# Формируем df
incorrect_df <- full_df %>%
select(VM.Name, 
IP.s, 
Owner,
Subsystem,
Creator,
Category,
Creation.Date,
isOwnerCorrect, 
isSubsystemCorrect, 
isCategoryCorrect,
isCreatorCorrect,
vCenter.Name) %>%
filter(isSubsystemCorrect == F | 
isOwnerCorrect == F |
isCategoryCorrect == F |
isCreatorCorrect == F)
# Проверяем существование файла со всеми ВМ и удаляем, если есть.
if (file.exists(filenameIncVM)) {file.remove(filenameIncVM)}
# Сохраняем список VM с незаполненными полями в csv
incorrect_df %>%
select(VM.Name) %>%
write_csv2(path = filenameIncVM, append = FALSE)
# Фильтруем для вставки в почту
incorrect_df_filtered <- incorrect_df %>% 
select(VM.Name, 
IP.s, 
Owner, 
Subsystem, 
Category,
Creator,
vCenter.Name,
Creation.Date
)
# Считаем количество строк
numberOfRows <- nrow(incorrect_df)
#### Начало условия ####
# Дальше либо у нас есть неправильно заполненные поля, либо нет.
# Если есть - запускаем ещё один скрипт
if (numberOfRows > 0) {
# Проверяем существование файла с создателями и удаляем, если есть.
if (file.exists(creatorsFilePath)) {file.remove(creatorsFilePath)}
# Запускаем PowerShell скрипт, который найдёт создателей найденных VM. На выходе получим csv.
system(paste0("powershell -File ", getCreatorsPath))
# Читаем файл с создателями
creators_df <- creatorsFilePath %>%
read.csv2(stringsAsFactors = FALSE)
# Фильтруем для вставки в почту, добавляем данные из таблицы с создателями
incorrect_df_filtered <- incorrect_df_filtered %>% 
select(VM.Name, 
IP.s, 
Owner, 
Subsystem, 
Category,
Creator,
vCenter.Name,
Creation.Date
) %>% 
left_join(creators_df, by = "VM.Name") %>% 
rename(`Предполагаемый создатель` = CreatedBy, 
`Предполагаемая дата создания` = CreatedOn)  
# Формируем тело письма
emailBody <- paste0(
'<html>
<h3>Добрый день, уважаемые коллеги.</h3>
<p>Полную актуальную информацию по виртуальным машинам вы можете посмотреть на диске H: вот тут:<p>
<p>\server.ruVM', sourceFileFormat, '</p>
<p>Также во вложении список ВМ с <strong>некорректно заполненными</strong> полями. Всего их <strong>', numberOfRows,'</strong>.</p>
<p>В таблице появилось 2 дополнительные колонки. <strong>Предполагаемый создатель</strong> и <strong>Предполагаемая дата создания</strong>, которые достаются из логов vCenter за последние 2 недели</p>
<p>Просьба создателей машин уточнить данные и заполнить поля корректно. Правила заполнения полей также во вложении</p>
<p><img src="data/meme.jpg"></p>
</html>'
)
# Проверяем существование файла
if (file.exists(filenameIncorrect)) {file.remove(filenameIncorrect)}
# Формируем красивую таблицу с форматами и т.д.
source(file = "email.R", local = T, encoding = "utf-8")
#### Формируем письмо с плохо подписанными машинами ####
send.mail(from = emailParams$from,
to = emailParams$to,
subject = "ВМ с некорректно заполненными полями",
body = emailBody,
encoding = "utf-8",
html = TRUE,
inline = TRUE,
smtp = emailParams$smtpParams,
authenticate = TRUE,
send = TRUE,
attach.files = c(filenameIncorrect, filenameVmCreationRules),
debug = FALSE)
#### Дальше пойдёт блок, если нет проблем с ВМ ####
} else {
# Формируем тело письма
emailBody <- paste0(
'<html>
<h3>Добрый день, уважаемые коллеги</h3>
<p>Полную актуальную информацию по виртуальным машинам вы можете посмотреть на диске H: вот тут:<p>
<p>\server.ruVM', sourceFileFormat, '</p>
<p>Также, на текущий момент, все поля ВМ корректно заполнены</p>
<p><img src="data/meme_correct.jpg"></p>
</html>'
)
#### Формируем письмо без плохо заполненных VM ####
send.mail(from = emailParams$from,
to = emailParams$to,
subject = "Сводная информация",
body = emailBody,
encoding = "utf-8",
html = TRUE,
inline = TRUE,
smtp = emailParams$smtpParams,
authenticate = TRUE,
send = TRUE,
debug = FALSE)
}
####### Записываем данные в БД #####
source(file = "DB.R", local = T, encoding = "utf-8")

ಪವರ್‌ಶೆಲ್‌ನಲ್ಲಿ ವಿಎಂ ಪಟ್ಟಿಯನ್ನು ಪಡೆಯಲು ಸ್ಕ್ರಿಪ್ಟ್

# Данные для подключения и другие переменные
$vCenterNames = @(
"vcenter01", 
"vcenter02", 
"vcenter03"
)
$vCenterUsername = "myusername"
$vCenterPassword = "mypassword"
$filename = "C:ScriptsgetVmdataallvmall-vm-$(get-date -f yyyy-MM-dd).csv"
$destinationSMB = "server.rumyfolder$vm"
$IP0=""
$IP1=""
$IP2=""
$IP3=""
$IP4=""
$IP5=""
# Подключение ко всем vCenter, что содержатся в переменной. Будет работать, если логин и пароль одинаковые (например, доменные)
Connect-VIServer -Server $vCenterNames -User $vCenterUsername -Password $vCenterPassword
write-host ""
# Создаём функцию с циклом по всем vCenter-ам
function Get-VMinventory {
# В этой переменной будет списко всех ВМ, как объектов
$AllVM = Get-VM | Sort Name
$cnt = $AllVM.Count
$count = 1
# Начинаем цикл по всем ВМ и собираем необходимые параметры каждого объекта
foreach ($vm in $AllVM) {
$StartTime = $(get-date)
$IP0 = $vm.Guest.IPAddress[0]
$IP1 = $vm.Guest.IPAddress[1]
$IP2 = $vm.Guest.IPAddress[2]
$IP3 = $vm.Guest.IPAddress[3]
$IP4 = $vm.Guest.IPAddress[4]
$IP5 = $vm.Guest.IPAddress[5]
If ($IP0 -ne $null) {If ($IP0.Contains(":") -ne 0) {$IP0=""}}
If ($IP1 -ne $null) {If ($IP1.Contains(":") -ne 0) {$IP1=""}}
If ($IP2 -ne $null) {If ($IP2.Contains(":") -ne 0) {$IP2=""}}
If ($IP3 -ne $null) {If ($IP3.Contains(":") -ne 0) {$IP3=""}}
If ($IP4 -ne $null) {If ($IP4.Contains(":") -ne 0) {$IP4=""}}
If ($IP5 -ne $null) {If ($IP5.Contains(":") -ne 0) {$IP5=""}}
$cluster = $vm | Get-Cluster | Select-Object -ExpandProperty name  
$Bootime = $vm.ExtensionData.Runtime.BootTime
$TotalHDDs = $vm.ProvisionedSpaceGB -as [int]
$CreationDate = $vm.CustomFields.Item("CreationDate") -as [string]
$Creator = $vm.CustomFields.Item("Creator") -as [string]
$Category = $vm.CustomFields.Item("Category") -as [string]
$Owner = $vm.CustomFields.Item("Owner") -as [string]
$Subsystem = $vm.CustomFields.Item("Subsystem") -as [string]
$IPS = $vm.CustomFields.Item("IP") -as [string]
$vCPU = $vm.NumCpu
$CorePerSocket = $vm.ExtensionData.config.hardware.NumCoresPerSocket
$Sockets = $vCPU/$CorePerSocket
$Id = $vm.Id.Split('-')[2] -as [int]
# Собираем все параметры в один объект
$Vmresult = New-Object PSObject
$Vmresult | add-member -MemberType NoteProperty -Name "Id" -Value $Id   
$Vmresult | add-member -MemberType NoteProperty -Name "VM Name" -Value $vm.Name  
$Vmresult | add-member -MemberType NoteProperty -Name "Cluster" -Value $cluster  
$Vmresult | add-member -MemberType NoteProperty -Name "Esxi Host" -Value $VM.VMHost  
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 1" -Value $IP0
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 2" -Value $IP1
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 3" -Value $IP2
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 4" -Value $IP3
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 5" -Value $IP4
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 6" -Value $IP5
$Vmresult | add-member -MemberType NoteProperty -Name "vCPU" -Value $vCPU
$Vmresult | Add-Member -MemberType NoteProperty -Name "CPU Sockets" -Value $Sockets
$Vmresult | Add-Member -MemberType NoteProperty -Name "Core per Socket" -Value $CorePerSocket
$Vmresult | add-member -MemberType NoteProperty -Name "RAM (GB)" -Value $vm.MemoryGB
$Vmresult | add-member -MemberType NoteProperty -Name "Total-HDD (GB)" -Value $TotalHDDs
$Vmresult | add-member -MemberType NoteProperty -Name "Power State" -Value $vm.PowerState
$Vmresult | add-member -MemberType NoteProperty -Name "OS" -Value $VM.ExtensionData.summary.config.guestfullname  
$Vmresult | Add-Member -MemberType NoteProperty -Name "Boot Time" -Value $Bootime
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Status" -Value $vm.ExtensionData.Guest.ToolsStatus  
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Version" -Value $vm.ExtensionData.Guest.ToolsVersion  
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Version Status" -Value $vm.ExtensionData.Guest.ToolsVersionStatus  
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Running Status" -Value $vm.ExtensionData.Guest.ToolsRunningStatus  
$Vmresult | add-member -MemberType NoteProperty -Name "Creation Date" -Value $CreationDate
$Vmresult | add-member -MemberType NoteProperty -Name "Creator" -Value $Creator
$Vmresult | add-member -MemberType NoteProperty -Name "Category" -Value $Category
$Vmresult | add-member -MemberType NoteProperty -Name "Owner" -Value $Owner
$Vmresult | add-member -MemberType NoteProperty -Name "Subsystem" -Value $Subsystem
$Vmresult | add-member -MemberType NoteProperty -Name "IP's" -Value $IPS
$Vmresult | add-member -MemberType NoteProperty -Name "vCenter Name" -Value $vm.Uid.Split('@')[1].Split(':')[0]  
# Считаем общее и оставшееся время выполнения и выводим на экран результаты. Использовалось для тестирования, но по факту оказалось очень удобно.
$elapsedTime = $(get-date) - $StartTime
$totalTime = "{0:HH:mm:ss}" -f ([datetime]($elapsedTime.Ticks*($cnt - $count)))
clear-host
Write-Host "Processing" $count "from" $cnt 
Write-host "Progress:" ([math]::Round($count/$cnt*100, 2)) "%" 
Write-host "You have about " $totalTime "for cofee"
Write-host ""
$count++
# Выводим результат, чтобы цикл "знал" что является результатом выполнения одного прохода
$Vmresult
}
}
# Вызываем получившуюся функцию и сразу выгружаем результат в csv
$allVm = Get-VMinventory | Export-CSV -Path $filename -NoTypeInformation -UseCulture -Force
# Пытаемся выложить полученный файл в нужное нам место и, в случае ошибки, пишем лог.
try
{
Copy-Item $filename -Destination $destinationSMB -Force -ErrorAction SilentlyContinue
}
catch
{
$error | Export-CSV -Path $filename".error" -NoTypeInformation -UseCulture -Force
}

ವರ್ಚುವಲ್ ಯಂತ್ರಗಳ ಸೃಷ್ಟಿಕರ್ತರು ಮತ್ತು ಅವುಗಳ ರಚನೆಯ ದಿನಾಂಕವನ್ನು ಲಾಗ್‌ಗಳಿಂದ ಹೊರತೆಗೆಯುವ ಪವರ್‌ಶೆಲ್ ಸ್ಕ್ರಿಪ್ಟ್

# Путь к файлу, из которого будем доставать список VM
$VMfilePath = "C:ScriptsgetVmcreators_VMcreators_VM_$(get-date -f yyyy-MM-dd).csv"
# Путь к файлу, в который будем записывать результат
$filePath = "C:ScriptsgetVmdatacreatorscreators-$(get-date -f yyyy-MM-dd).csv"
# Создаём вокрфлоу
Workflow GetCreators-Wf
{
# Параметры, которые можно будет передать при вызове скрипта
param([string[]]$VMfilePath)
# Параметры, которые доступны только внутри workflow
$vCenterUsername = "myusername"
$vCenterPassword = "mypassword"
$daysToLook = 14
$start = (get-date).AddDays(-$daysToLook)
$finish = get-date
# Значения, которые будут вписаны в csv для машин, по которым не будет ничего найдено
$UnknownUser = "UNKNOWN"
$UnknownCreatedTime = "0000-00-00"
# Определяем параметры подключения и выводной файл, которые будут доступны во всём скрипте.
$vCenterNames = @(
"vcenter01", 
"vcenter02", 
"vcenter03"
)
# Получаем список VM из csv и загружаем соответствующие объекты
$list = Import-Csv $VMfilePath -UseCulture | select -ExpandProperty VM.Name
# Цикл, который будет выполняться параллельно (по 5 машин за раз)
foreach -parallel ($row in $list)
{
# Это скрипт, который видит только свои переменные и те, которые ему переданы через $Using
InlineScript {
# Время начала выполнения отдельного блока
$StartTime = $(get-date)
Write-Host ""
Write-Host "Processing $Using:row started at $StartTime"
Write-Host ""
# Подключение оборачиваем в переменную, чтобы информация о нём не мешалась в консоли
$con = Connect-VIServer -Server $Using:vCenterNames -User $Using:vCenterUsername -Password $Using:vCenterPassword
# Получаем объект vm
$vm = Get-VM -Name $Using:row
# Ниже 2 одинаковые команды. Одна с фильтром по времени, вторая - без. Можно пользоваться тем,
$Event = $vm | Get-VIEvent -Start $Using:start -Finish $Using:finish -Types Info | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent" -or $_.Gettype().Name -eq "VmClonedEvent"}
# $Event = $vm | Get-VIEvent -Types Info | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent" -or $_.Gettype().Name -eq "VmClonedEvent"}
# Заполняем параметры в зависимости от того, удалось ли в логах найти что-то
If (($Event | Measure-Object).Count -eq 0){
$User = $Using:UnknownUser
$Created = $Using:UnknownCreatedTime
$CreatedFormat = $Using:UnknownCreatedTime
} Else {
If ($Event.Username -eq "" -or $Event.Username -eq $null) {
$User = $Using:UnknownUser
} Else {
$User = $Event.Username
} # Else
$CreatedFormat = $Event.CreatedTime
# Один из коллег отдельно просил, чтобы время было в таком формате, поэтому дублируем его. А в БД пойдёт нормальный формат.
$Created = $Event.CreatedTime.ToString('yyyy-MM-dd')
} # Else
Write-Host "Creator for $vm is $User. Creating object."
# Создаём объект. Добавляем параметры.
$Vmresult = New-Object PSObject
$Vmresult | add-member -MemberType NoteProperty -Name "VM Name" -Value $vm.Name  
$Vmresult | add-member -MemberType NoteProperty -Name "CreatedBy" -Value $User
$Vmresult | add-member -MemberType NoteProperty -Name "CreatedOn" -Value $CreatedFormat
$Vmresult | add-member -MemberType NoteProperty -Name "CreatedOnFormat" -Value $Created           
# Выводим результаты
$Vmresult
} # Inline
} # ForEach
}
$Creators = GetCreators-Wf $VMfilePath
# Записываем результат в файл
$Creators | select 'VM Name', CreatedBy, CreatedOn | Export-Csv -Path $filePath -NoTypeInformation -UseCulture -Force
Write-Host "CSV generetion finisghed at $(get-date). PROFIT"

ಗ್ರಂಥಾಲಯವು ವಿಶೇಷ ಗಮನಕ್ಕೆ ಅರ್ಹವಾಗಿದೆ xlsx, ಇದು ಅಕ್ಷರದ ಲಗತ್ತನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಿಸಿತು (ನಿರ್ವಹಣೆಯು ಇಷ್ಟಪಟ್ಟಂತೆ), ಮತ್ತು ಕೇವಲ CSV ಟೇಬಲ್ ಅಲ್ಲ.

ಯಂತ್ರಗಳಲ್ಲಿ ತಪ್ಪಾಗಿ ತುಂಬಿದ ಪಟ್ಟಿಯೊಂದಿಗೆ ಸುಂದರವಾದ xlsx ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ

# Создаём новую книгу
# Возможные значения : "xls" и "xlsx"
wb<-createWorkbook(type="xlsx")
# Стили для имён рядов и колонок в таблицах
TABLE_ROWNAMES_STYLE <- CellStyle(wb) + Font(wb, isBold=TRUE)
TABLE_COLNAMES_STYLE <- CellStyle(wb) + Font(wb, isBold=TRUE) +
Alignment(wrapText=TRUE, horizontal="ALIGN_CENTER") +
Border(color="black", position=c("TOP", "BOTTOM"), 
pen=c("BORDER_THIN", "BORDER_THICK"))
# Создаём новый лист
sheet <- createSheet(wb, sheetName = names[2])
# Добавляем таблицу
addDataFrame(incorrect_df_filtered, 
sheet, startRow=1, startColumn=1,  row.names=FALSE, byrow=FALSE,
colnamesStyle = TABLE_COLNAMES_STYLE,
rownamesStyle = TABLE_ROWNAMES_STYLE)
# Меняем ширину, чтобы форматирование было автоматическим
autoSizeColumn(sheet = sheet, colIndex=c(1:ncol(incorrect_df)))
# Добавляем фильтры
addAutoFilter(sheet, cellRange = "C1:G1")
# Определяем стиль
fo2 <- Fill(foregroundColor="red")
cs2 <- CellStyle(wb, 
fill = fo2, 
dataFormat = DataFormat("@"))
# Находим ряды с неверно заполненным полем Владельца и применяем к ним определённый стиль
rowsOwner <- getRows(sheet, rowIndex = (which(!incorrect_df$isOwnerCorrect) + 1))
cellsOwner <- getCells(rowsOwner, colIndex = which( colnames(incorrect_df_filtered) == "Owner" )) 
lapply(names(cellsOwner), function(x) setCellStyle(cellsOwner[[x]], cs2))
# Находим ряды с неверно заполненным полем Подсистемы и применяем к ним определённый стиль
rowsSubsystem <- getRows(sheet, rowIndex = (which(!incorrect_df$isSubsystemCorrect) + 1))
cellsSubsystem <- getCells(rowsSubsystem, colIndex = which( colnames(incorrect_df_filtered) == "Subsystem" )) 
lapply(names(cellsSubsystem), function(x) setCellStyle(cellsSubsystem[[x]], cs2))
# Аналогично по Категории
rowsCategory <- getRows(sheet, rowIndex = (which(!incorrect_df$isCategoryCorrect) + 1))
cellsCategory <- getCells(rowsCategory, colIndex = which( colnames(incorrect_df_filtered) == "Category" )) 
lapply(names(cellsCategory), function(x) setCellStyle(cellsCategory[[x]], cs2))
# Создатель
rowsCreator <- getRows(sheet, rowIndex = (which(!incorrect_df$isCreatorCorrect) + 1))
cellsCreator <- getCells(rowsCreator, colIndex = which( colnames(incorrect_df_filtered) == "Creator" )) 
lapply(names(cellsCreator), function(x) setCellStyle(cellsCreator[[x]], cs2))
# Сохраняем файл
saveWorkbook(wb, filenameIncorrect)

ಔಟ್ಪುಟ್ ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:

R ಮತ್ತು PowerShell ಅನ್ನು ಬಳಸಿಕೊಂಡು ವರ್ಚುವಲ್ ಯಂತ್ರಗಳ ಆರೋಗ್ಯದ ಕುರಿತು ದೈನಂದಿನ ವರದಿಗಳು

ವಿಂಡೋಸ್ ಶೆಡ್ಯೂಲರ್ ಅನ್ನು ಹೊಂದಿಸುವ ಬಗ್ಗೆ ಆಸಕ್ತಿದಾಯಕ ಸೂಕ್ಷ್ಮ ವ್ಯತ್ಯಾಸವೂ ಇತ್ತು. ಸರಿಯಾದ ಹಕ್ಕುಗಳು ಮತ್ತು ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಕಂಡುಹಿಡಿಯುವುದು ಅಸಾಧ್ಯ, ಇದರಿಂದ ಎಲ್ಲವೂ ಪ್ರಾರಂಭವಾಗಬೇಕು. ಪರಿಣಾಮವಾಗಿ, R ಲೈಬ್ರರಿ ಕಂಡುಬಂದಿದೆ, ಇದು ಸ್ವತಃ R ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು ಕಾರ್ಯವನ್ನು ರಚಿಸುತ್ತದೆ ಮತ್ತು ಲಾಗ್ ಫೈಲ್ ಬಗ್ಗೆ ಸಹ ಮರೆಯುವುದಿಲ್ಲ. ನಂತರ ನೀವು ಕೆಲಸವನ್ನು ಹಸ್ತಚಾಲಿತವಾಗಿ ಸರಿಪಡಿಸಬಹುದು.

ವಿಂಡೋಸ್ ಶೆಡ್ಯೂಲರ್‌ನಲ್ಲಿ ಕಾರ್ಯವನ್ನು ರಚಿಸುವ ಎರಡು ಉದಾಹರಣೆಗಳೊಂದಿಗೆ R ಕೋಡ್‌ನ ತುಂಡು

library(taskscheduleR)
myscript <- file.path(getwd(), "all_vm.R")
## запускаем скрипт через 62 секунды
taskscheduler_create(taskname = "getAllVm", rscript = myscript, 
schedule = "ONCE", starttime = format(Sys.time() + 62, "%H:%M"))
## запускаем скрипт каждый день в 09:10
taskscheduler_create(taskname = "getAllVmDaily", rscript = myscript, 
schedule = "WEEKLY", 
days = c("MON", "TUE", "WED", "THU", "FRI"),
starttime = "02:00")
## удаляем задачи
taskscheduler_delete(taskname = "getAllVm")
taskscheduler_delete(taskname = "getAllVmDaily")
# Смотрим логи (последние 4 строчки)
tail(readLines("all_vm.log"), sep ="n", n = 4)

ಡೇಟಾಬೇಸ್ ಬಗ್ಗೆ ಪ್ರತ್ಯೇಕವಾಗಿ

ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಹೊಂದಿಸಿದ ನಂತರ, ಇತರ ಸಮಸ್ಯೆಗಳು ಕಾಣಿಸಿಕೊಳ್ಳಲು ಪ್ರಾರಂಭಿಸಿದವು. ಉದಾಹರಣೆಗೆ, VM ಅನ್ನು ಅಳಿಸಿದಾಗ ದಿನಾಂಕವನ್ನು ಕಂಡುಹಿಡಿಯಲು ನಾನು ಬಯಸುತ್ತೇನೆ, ಆದರೆ vCenter ನಲ್ಲಿನ ಲಾಗ್‌ಗಳು ಈಗಾಗಲೇ ಸವೆದುಹೋಗಿವೆ. ಸ್ಕ್ರಿಪ್ಟ್ ಪ್ರತಿದಿನ ಫೈಲ್‌ಗಳನ್ನು ಫೋಲ್ಡರ್‌ನಲ್ಲಿ ಇರಿಸುತ್ತದೆ ಮತ್ತು ಅದನ್ನು ಸ್ವಚ್ಛಗೊಳಿಸುವುದಿಲ್ಲ (ನಾವು ನೆನಪಿಸಿಕೊಂಡಾಗ ನಾವು ಅದನ್ನು ನಮ್ಮ ಕೈಗಳಿಂದ ಸ್ವಚ್ಛಗೊಳಿಸುತ್ತೇವೆ), ನೀವು ಹಳೆಯ ಫೈಲ್‌ಗಳನ್ನು ನೋಡಬಹುದು ಮತ್ತು ಈ VM ಇಲ್ಲದಿರುವ ಮೊದಲ ಫೈಲ್ ಅನ್ನು ಕಂಡುಹಿಡಿಯಬಹುದು. ಆದರೆ ಅದು ತಂಪಾಗಿಲ್ಲ.

ನಾನು ಐತಿಹಾಸಿಕ ಡೇಟಾಬೇಸ್ ರಚಿಸಲು ಬಯಸುತ್ತೇನೆ.

MS SQL ಸರ್ವರ್ - ಸಿಸ್ಟಮ್-ಆವೃತ್ತಿಯ ಟೆಂಪೋರಲ್ ಟೇಬಲ್‌ನ ಕಾರ್ಯವು ರಕ್ಷಣೆಗೆ ಬಂದಿತು. ಇದನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ತಾತ್ಕಾಲಿಕ (ತಾತ್ಕಾಲಿಕವಲ್ಲ) ಕೋಷ್ಟಕಗಳಾಗಿ ಅನುವಾದಿಸಲಾಗುತ್ತದೆ.

ನೀವು ವಿವರವಾಗಿ ಓದಬಹುದು ಅಧಿಕೃತ ಮೈಕ್ರೋಸಾಫ್ಟ್ ದಸ್ತಾವೇಜನ್ನು.

ಸಂಕ್ಷಿಪ್ತವಾಗಿ ಹೇಳುವುದಾದರೆ, ನಾವು ಟೇಬಲ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ, ನಾವು ಅದನ್ನು ಆವೃತ್ತಿಯೊಂದಿಗೆ ಹೊಂದಿದ್ದೇವೆ ಎಂದು ಹೇಳುತ್ತೇವೆ ಮತ್ತು SQL ಸರ್ವರ್ ಈ ಕೋಷ್ಟಕದಲ್ಲಿ 2 ಹೆಚ್ಚುವರಿ ದಿನಾಂಕ ಕಾಲಮ್‌ಗಳನ್ನು ರಚಿಸುತ್ತದೆ (ದಾಖಲೆಯನ್ನು ರಚಿಸಿದ ದಿನಾಂಕ ಮತ್ತು ದಾಖಲೆಯ ಮುಕ್ತಾಯ ದಿನಾಂಕ) ಮತ್ತು ಹೆಚ್ಚುವರಿ ಕೋಷ್ಟಕವನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ ಬರೆಯಲಾಗುವುದು. ಪರಿಣಾಮವಾಗಿ, ನಾವು ನವೀಕೃತ ಮಾಹಿತಿಯನ್ನು ಸ್ವೀಕರಿಸುತ್ತೇವೆ ಮತ್ತು ಸರಳ ಪ್ರಶ್ನೆಗಳ ಮೂಲಕ, ದಾಖಲಾತಿಯಲ್ಲಿ ನೀಡಲಾದ ಉದಾಹರಣೆಗಳ ಮೂಲಕ, ನಾವು ನಿರ್ದಿಷ್ಟ ವರ್ಚುವಲ್ ಯಂತ್ರದ ಜೀವನ ಚಕ್ರವನ್ನು ಅಥವಾ ಒಂದು ನಿರ್ದಿಷ್ಟ ಹಂತದಲ್ಲಿ ಎಲ್ಲಾ VM ಗಳ ಸ್ಥಿತಿಯನ್ನು ನೋಡಬಹುದು. ಸಮಯದಲ್ಲಿ.

ಕಾರ್ಯಕ್ಷಮತೆಯ ದೃಷ್ಟಿಕೋನದಿಂದ, ತಾತ್ಕಾಲಿಕ ಟೇಬಲ್‌ಗೆ ಬರೆಯುವ ವಹಿವಾಟು ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ ಮುಖ್ಯ ಕೋಷ್ಟಕಕ್ಕೆ ಬರೆಯುವ ವಹಿವಾಟು ಪೂರ್ಣಗೊಳ್ಳುವುದಿಲ್ಲ. ಆ. ಹೆಚ್ಚಿನ ಸಂಖ್ಯೆಯ ಬರೆಯುವ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಹೊಂದಿರುವ ಕೋಷ್ಟಕಗಳಲ್ಲಿ, ಈ ಕಾರ್ಯವನ್ನು ಎಚ್ಚರಿಕೆಯಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕು, ಆದರೆ ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ ಇದು ನಿಜವಾಗಿಯೂ ತಂಪಾದ ವಿಷಯವಾಗಿದೆ.

ಯಾಂತ್ರಿಕ ವ್ಯವಸ್ಥೆಯು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸಲು, ನಾನು R ನಲ್ಲಿ ಒಂದು ಸಣ್ಣ ಕೋಡ್ ಅನ್ನು ಸೇರಿಸಬೇಕಾಗಿತ್ತು, ಅದು ಹೊಸ ಟೇಬಲ್ ಅನ್ನು ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಒಂದರೊಂದಿಗೆ ಎಲ್ಲಾ VM ಗಳ ಡೇಟಾದೊಂದಿಗೆ ಹೋಲಿಸುತ್ತದೆ ಮತ್ತು ಅದಕ್ಕೆ ಬದಲಾದ ಸಾಲುಗಳನ್ನು ಮಾತ್ರ ಬರೆಯುತ್ತದೆ. ಕೋಡ್ ವಿಶೇಷವಾಗಿ ಬುದ್ಧಿವಂತವಾಗಿಲ್ಲ; ಇದು compareDF ಲೈಬ್ರರಿಯನ್ನು ಬಳಸುತ್ತದೆ, ಆದರೆ ನಾನು ಅದನ್ನು ಕೆಳಗೆ ಪ್ರಸ್ತುತಪಡಿಸುತ್ತೇನೆ.

ಡೇಟಾಬೇಸ್‌ಗೆ ಡೇಟಾವನ್ನು ಬರೆಯಲು R ಕೋಡ್

# Подцепляем пакеты
library(odbc)
library(compareDF)
# Формируем коннект
con <- dbConnect(odbc(),
Driver = "ODBC Driver 13 for SQL Server",
Server = DBParams$server,
Database = DBParams$database,
UID = DBParams$UID,
PWD = DBParams$PWD,
Port = 1433)
#### Проверяем есть ли таблица. Если нет - создаём. ####
if (!dbExistsTable(con, DBParams$TblName)) {
#### Создаём таблицу ####
create <- dbSendStatement(
con,
paste0(
'CREATE TABLE ',
DBParams$TblName,
'(
[Id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[VM.Name] [varchar](255) NULL,
[Cluster] [varchar](255) NULL,
[Esxi.Host] [varchar](255) NULL,
[IP.Address.1] [varchar](255) NULL,
[IP.Address.2] [varchar](255) NULL,
[IP.Address.3] [varchar](255) NULL,
[IP.Address.4] [varchar](255) NULL,
[IP.Address.5] [varchar](255) NULL,
[IP.Address.6] [varchar](255) NULL,
[vCPU] [int] NULL,
[CPU.Sockets] [int] NULL,
[Core.per.Socket] [int] NULL,
[RAM..GB.] [int] NULL,
[Total.HDD..GB.] [int] NULL,
[Power.State] [varchar](255) NULL,
[OS] [varchar](255) NULL,
[Boot.Time] [varchar](255) NULL,
[VMTools.Status] [varchar](255) NULL,
[VMTools.Version] [int] NULL,
[VMTools.Version.Status] [varchar](255) NULL,
[VMTools.Running.Status] [varchar](255) NULL,
[Creation.Date] [varchar](255) NULL,
[Creator] [varchar](255) NULL,
[Category] [varchar](255) NULL,
[Owner] [varchar](255) NULL,
[Subsystem] [varchar](255) NULL,
[IP.s] [varchar](255) NULL,
[vCenter.Name] [varchar](255) NULL,
DateFrom datetime2 GENERATED ALWAYS AS ROW START NOT NULL,
DateTo datetime2 GENERATED ALWAYS AS ROW END NOT NULL,
PERIOD FOR SYSTEM_TIME (DateFrom, DateTo)
) ON [PRIMARY]
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = ', DBParams$TblHistName,'));'
)
)
# Отправляем подготовленный запрос
dbClearResult(create)
} # if
#### Начало работы с таблицей ####
# Обозначаем таблицу, с которой будем работать
allVM_db_con <- tbl(con, DBParams$TblName) 
#### Сравниваем таблицы ####
# Собираем данные с таблицы (убираем служебные временные поля)
allVM_db <- allVM_db_con %>% 
select(c(-"DateTo", -"DateFrom")) %>% 
collect()
# Создаём таблицу со сравнением объектов. Сравниваем по Id
# Удалённые объекты там будут помечены через -, созданные через +, изменённые через - и +
ctable_VM <- fullXslx_df %>% 
compare_df(allVM_db, 
c("Id"))
#### Удаление строк ####
# Выдираем Id виртуалок, записи о которых надо удалить 
remove_Id <- ctable_VM$comparison_df %>% 
filter(chng_type == "-") %>%
select(Id)
# Проверяем, что есть записи (если записей нет - и удалять ничего не нужно)
if (remove_Id %>% nrow() > 0) {
# Конструируем шаблон для запроса на удаление данных
delete <- dbSendStatement(con, 
paste0('
DELETE 
FROM ',
DBParams$TblName,
' WHERE "Id"=?
') # paste
) # send
# Создаём запрос на удаление данных
dbBind(delete, remove_Id)
# Отправляем подготовленный запрос
dbClearResult(delete)
} # if
#### Добавление строк ####
# Выделяем таблицу, содержащую строки, которые нужно добавить.
allVM_add <- ctable_VM$comparison_df %>% 
filter(chng_type == "+") %>% 
select(-chng_type)
# Проверяем, есть ли строки, которые нужно добавить и добавляем (если нет - не добавляем)
if (allVM_add %>% nrow() > 0) {
# Пишем таблицу со всеми необходимыми данными
dbWriteTable(con,
DBParams$TblName,
allVM_add,
overwrite = FALSE,
append = TRUE)
} # if
#### Не забываем сделать дисконнект ####
dbDisconnect(con)

ಒಟ್ಟು

ಸ್ಕ್ರಿಪ್ಟ್ ಅನುಷ್ಠಾನದ ಪರಿಣಾಮವಾಗಿ, ಕ್ರಮವನ್ನು ಪುನಃಸ್ಥಾಪಿಸಲಾಯಿತು ಮತ್ತು ಕೆಲವು ತಿಂಗಳುಗಳಲ್ಲಿ ನಿರ್ವಹಿಸಲಾಯಿತು. ಕೆಲವೊಮ್ಮೆ ತಪ್ಪಾಗಿ ತುಂಬಿದ VM ಗಳು ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ, ಆದರೆ ಸ್ಕ್ರಿಪ್ಟ್ ಉತ್ತಮ ಜ್ಞಾಪನೆಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅಪರೂಪದ VM ಸತತವಾಗಿ 2 ದಿನಗಳವರೆಗೆ ಪಟ್ಟಿಗೆ ಸೇರುತ್ತದೆ.

ಐತಿಹಾಸಿಕ ದತ್ತಾಂಶವನ್ನು ವಿಶ್ಲೇಷಿಸಲು ತಳಹದಿಯನ್ನು ಸಹ ಮಾಡಲಾಗಿದೆ.

ಇದರಲ್ಲಿ ಹೆಚ್ಚಿನದನ್ನು ಮೊಣಕಾಲಿನ ಮೇಲೆ ಅಲ್ಲ, ಆದರೆ ವಿಶೇಷ ಸಾಫ್ಟ್‌ವೇರ್‌ನೊಂದಿಗೆ ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು ಎಂಬುದು ಸ್ಪಷ್ಟವಾಗಿದೆ, ಆದರೆ ಕಾರ್ಯವು ಆಸಕ್ತಿದಾಯಕವಾಗಿದೆ ಮತ್ತು ಒಬ್ಬರು ಹೇಳಬಹುದು, ಐಚ್ಛಿಕ.

ಆರ್ ಮತ್ತೊಮ್ಮೆ ಅತ್ಯುತ್ತಮ ಸಾರ್ವತ್ರಿಕ ಭಾಷೆ ಎಂದು ತೋರಿಸಿದೆ, ಇದು ಅಂಕಿಅಂಶಗಳ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಹರಿಸಲು ಮಾತ್ರವಲ್ಲದೆ ಇತರ ಡೇಟಾ ಮೂಲಗಳ ನಡುವೆ ಅತ್ಯುತ್ತಮವಾದ "ಲೇಯರ್" ಆಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ.

R ಮತ್ತು PowerShell ಅನ್ನು ಬಳಸಿಕೊಂಡು ವರ್ಚುವಲ್ ಯಂತ್ರಗಳ ಆರೋಗ್ಯದ ಕುರಿತು ದೈನಂದಿನ ವರದಿಗಳು

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ